From 0be27d8f1cb9d1a3002c1a60fbd05310d8a7fb99 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Wed, 6 Oct 2010 09:34:49 +0100 Subject: [PATCH 001/110] BUG#56343 binlog_cache_use status is bigger than expected The binlog_cache_use is incremented twice when changes to a transactional table are committed, i.e. TC_LOG_BINLOG::log_xid calls is called. The problem happens because log_xid calls both binlog_flush_stmt_cache and binlog_flush_trx_cache without checking if such caches are empty thus unintentionally increasing the binlog_cache_use value twice. To fix the problem we avoided incrementing the binlog_cache_use if the cache is empty. We also decided to increment binlog_cache_use when the cache is truncated as the cache is used although its content is discarded and is not written to the binary log. Note that binlog_cache_use is incremented for both types of cache, transactional and non-transactional and that the behavior presented in this patch also applies to the binlog_cache_disk_use. Finally, we re-organized the code around the functions binlog_flush_trx_cache and binlog_flush_stmt_cache. --- .../extra/binlog_tests/binlog_cache_stat.test | 129 ++++++++ .../extra/binlog_tests/innodb_stat.test | 41 --- .../suite/binlog/r/binlog_innodb.result | 4 +- .../binlog/r/binlog_mix_innodb_stat.result | 25 -- .../binlog/r/binlog_mixed_cache_stat.result | 120 +++++++ .../binlog/r/binlog_row_cache_stat.result | 120 +++++++ .../binlog/r/binlog_row_innodb_stat.result | 25 -- .../binlog/r/binlog_stm_cache_stat.result | 120 +++++++ .../binlog/r/binlog_stm_innodb_stat.result | 25 -- ...stat.test => binlog_mixed_cache_stat.test} | 2 +- ...b_stat.test => binlog_row_cache_stat.test} | 2 +- ...b_stat.test => binlog_stm_cache_stat.test} | 2 +- sql/log.cc | 308 ++++++++++-------- sql/log_event.cc | 25 ++ sql/log_event.h | 2 +- 15 files changed, 701 insertions(+), 249 deletions(-) create mode 100644 mysql-test/extra/binlog_tests/binlog_cache_stat.test delete mode 100644 mysql-test/extra/binlog_tests/innodb_stat.test delete mode 100644 mysql-test/suite/binlog/r/binlog_mix_innodb_stat.result create mode 100644 mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result create mode 100644 mysql-test/suite/binlog/r/binlog_row_cache_stat.result delete mode 100644 mysql-test/suite/binlog/r/binlog_row_innodb_stat.result create mode 100644 mysql-test/suite/binlog/r/binlog_stm_cache_stat.result delete mode 100644 mysql-test/suite/binlog/r/binlog_stm_innodb_stat.result rename mysql-test/suite/binlog/t/{binlog_mix_innodb_stat.test => binlog_mixed_cache_stat.test} (77%) rename mysql-test/suite/binlog/t/{binlog_row_innodb_stat.test => binlog_row_cache_stat.test} (77%) rename mysql-test/suite/binlog/t/{binlog_stm_innodb_stat.test => binlog_stm_cache_stat.test} (78%) diff --git a/mysql-test/extra/binlog_tests/binlog_cache_stat.test b/mysql-test/extra/binlog_tests/binlog_cache_stat.test new file mode 100644 index 00000000000..c7b885179d1 --- /dev/null +++ b/mysql-test/extra/binlog_tests/binlog_cache_stat.test @@ -0,0 +1,129 @@ +# Embedded server doesn't support binlog +-- source include/not_embedded.inc +-- source include/have_innodb.inc + +# Creating tables +--disable_warnings +drop table if exists t1, t2; +--enable_warnings + +create table t1 (a int) engine=innodb; +create table t2 (a int) engine=myisam; + +# +# Let us test binlog_cache_use and binlog_cache_disk_use status vars. +# Actually this test has nothing to do with innodb per se, it just +# requires transactional table. +# +# This test checks binlog_cache_use and binlog_cache_disk_use when +# transactions are committed and after when they are aborted. +# + +# +# Checking commit. +# +--echo **** Preparing the enviroment to check commit and its effect on +--echo **** the binlog_cache_use and binlog_cache_disk_use. +--echo **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +flush status; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +--echo **** Now we are going to create transactional changes which are long enough so +--echo **** they will be flushed to disk... +--echo **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +let $1=2000; +disable_query_log; +begin; +while ($1) +{ + eval insert into t1 values( $1 ); + dec $1; +} +commit; +enable_query_log; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +--echo **** Transactional changes which should not be flushed to disk and so should not +--echo **** increase binlog_cache_disk_use. +--echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +commit; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +--echo **** Non-Transactional changes which should not be flushed to disk and so should not +--echo **** increase binlog_cache_disk_use. +--echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +begin; +insert into t2 values( 1 ); +commit; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +--echo **** Mixed changes which should not be flushed to disk and so should not +--echo **** increase binlog_cache_disk_use. +--echo **** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +insert into t2 values( 1 ); +commit; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +# +# Checking abort. +# +--echo **** Preparing the enviroment to check abort and its effect on +--echo **** the binlog_cache_use and binlog_cache_disk_use +--echo **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +flush status; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +--echo **** Now we are going to create transactional changes which are long enough so +--echo **** they will be flushed to disk... +--echo **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +let $1=2000; +disable_query_log; +begin; +while ($1) +{ + eval insert into t1 values( $1 ); + dec $1; +} +rollback; +enable_query_log; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +--echo **** Transactional changes which should not be flushed to disk and so should not +--echo **** increase binlog_cache_disk_use. +--echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +rollback; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +--echo **** Non-Transactional changes which should not be flushed to disk and so should not +--echo **** increase binlog_cache_disk_use. +--echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +begin; +insert into t2 values( 1 ); +rollback; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +--echo **** Mixed changes which should not be flushed to disk and so should not +--echo **** increase binlog_cache_disk_use. +--echo **** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +insert into t2 values( 1 ); +rollback; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; +drop table t1, t2; diff --git a/mysql-test/extra/binlog_tests/innodb_stat.test b/mysql-test/extra/binlog_tests/innodb_stat.test deleted file mode 100644 index b31e99dfe71..00000000000 --- a/mysql-test/extra/binlog_tests/innodb_stat.test +++ /dev/null @@ -1,41 +0,0 @@ -# Embedded server doesn't support binlog --- source include/not_embedded.inc --- source include/have_innodb.inc - -# -# Let us test binlog_cache_use and binlog_cache_disk_use status vars. -# Actually this test has nothing to do with innodb per se, it just requires -# transactional table. -# -flush status; -show status like "binlog_cache_use"; -show status like "binlog_cache_disk_use"; ---disable_warnings -drop table if exists t1; ---enable_warnings - -create table t1 (a int) engine=innodb; - -# Now we are going to create transaction which is long enough so its -# transaction binlog will be flushed to disk... -let $1=2000; -disable_query_log; -begin; -while ($1) -{ - eval insert into t1 values( $1 ); - dec $1; -} -commit; -enable_query_log; -show status like "binlog_cache_use"; -show status like "binlog_cache_disk_use"; - -# Transaction which should not be flushed to disk and so should not -# increase binlog_cache_disk_use. -begin; -delete from t1; -commit; -show status like "binlog_cache_use"; -show status like "binlog_cache_disk_use"; -drop table t1; diff --git a/mysql-test/suite/binlog/r/binlog_innodb.result b/mysql-test/suite/binlog/r/binlog_innodb.result index dc170361026..cdb72aad902 100644 --- a/mysql-test/suite/binlog/r/binlog_innodb.result +++ b/mysql-test/suite/binlog/r/binlog_innodb.result @@ -123,7 +123,7 @@ Binlog_cache_disk_use 0 create table t1 (a int) engine=innodb; show status like "binlog_cache_use"; Variable_name Value -Binlog_cache_use 2 +Binlog_cache_use 1 show status like "binlog_cache_disk_use"; Variable_name Value Binlog_cache_disk_use 1 @@ -132,7 +132,7 @@ delete from t1; commit; show status like "binlog_cache_use"; Variable_name Value -Binlog_cache_use 4 +Binlog_cache_use 2 show status like "binlog_cache_disk_use"; Variable_name Value Binlog_cache_disk_use 1 diff --git a/mysql-test/suite/binlog/r/binlog_mix_innodb_stat.result b/mysql-test/suite/binlog/r/binlog_mix_innodb_stat.result deleted file mode 100644 index 637be940383..00000000000 --- a/mysql-test/suite/binlog/r/binlog_mix_innodb_stat.result +++ /dev/null @@ -1,25 +0,0 @@ -flush status; -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 0 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 0 -drop table if exists t1; -create table t1 (a int) engine=innodb; -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 2 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 1 -begin; -delete from t1; -commit; -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 4 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 1 -drop table t1; diff --git a/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result b/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result new file mode 100644 index 00000000000..b0af247074b --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result @@ -0,0 +1,120 @@ +drop table if exists t1, t2; +create table t1 (a int) engine=innodb; +create table t2 (a int) engine=myisam; +**** Preparing the enviroment to check commit and its effect on +**** the binlog_cache_use and binlog_cache_disk_use. +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +flush status; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 0 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 0 +**** Now we are going to create transactional changes which are long enough so +**** they will be flushed to disk... +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 2 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Non-Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +begin; +insert into t2 values( 1 ); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 3 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Mixed changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +insert into t2 values( 1 ); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 5 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Preparing the enviroment to check abort and its effect on +**** the binlog_cache_use and binlog_cache_disk_use +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +flush status; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 0 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 0 +**** Now we are going to create transactional changes which are long enough so +**** they will be flushed to disk... +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +rollback; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 2 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Non-Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +begin; +insert into t2 values( 1 ); +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 3 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Mixed changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +insert into t2 values( 1 ); +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 5 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +drop table t1, t2; diff --git a/mysql-test/suite/binlog/r/binlog_row_cache_stat.result b/mysql-test/suite/binlog/r/binlog_row_cache_stat.result new file mode 100644 index 00000000000..b0af247074b --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_row_cache_stat.result @@ -0,0 +1,120 @@ +drop table if exists t1, t2; +create table t1 (a int) engine=innodb; +create table t2 (a int) engine=myisam; +**** Preparing the enviroment to check commit and its effect on +**** the binlog_cache_use and binlog_cache_disk_use. +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +flush status; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 0 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 0 +**** Now we are going to create transactional changes which are long enough so +**** they will be flushed to disk... +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 2 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Non-Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +begin; +insert into t2 values( 1 ); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 3 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Mixed changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +insert into t2 values( 1 ); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 5 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Preparing the enviroment to check abort and its effect on +**** the binlog_cache_use and binlog_cache_disk_use +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +flush status; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 0 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 0 +**** Now we are going to create transactional changes which are long enough so +**** they will be flushed to disk... +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +rollback; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 2 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Non-Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +begin; +insert into t2 values( 1 ); +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 3 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Mixed changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +insert into t2 values( 1 ); +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 5 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +drop table t1, t2; diff --git a/mysql-test/suite/binlog/r/binlog_row_innodb_stat.result b/mysql-test/suite/binlog/r/binlog_row_innodb_stat.result deleted file mode 100644 index 637be940383..00000000000 --- a/mysql-test/suite/binlog/r/binlog_row_innodb_stat.result +++ /dev/null @@ -1,25 +0,0 @@ -flush status; -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 0 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 0 -drop table if exists t1; -create table t1 (a int) engine=innodb; -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 2 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 1 -begin; -delete from t1; -commit; -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 4 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 1 -drop table t1; diff --git a/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result b/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result new file mode 100644 index 00000000000..b0af247074b --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result @@ -0,0 +1,120 @@ +drop table if exists t1, t2; +create table t1 (a int) engine=innodb; +create table t2 (a int) engine=myisam; +**** Preparing the enviroment to check commit and its effect on +**** the binlog_cache_use and binlog_cache_disk_use. +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +flush status; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 0 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 0 +**** Now we are going to create transactional changes which are long enough so +**** they will be flushed to disk... +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 2 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Non-Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +begin; +insert into t2 values( 1 ); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 3 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Mixed changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +insert into t2 values( 1 ); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 5 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Preparing the enviroment to check abort and its effect on +**** the binlog_cache_use and binlog_cache_disk_use +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +flush status; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 0 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 0 +**** Now we are going to create transactional changes which are long enough so +**** they will be flushed to disk... +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +rollback; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 2 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Non-Transactional changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +begin; +insert into t2 values( 1 ); +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 3 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +**** Mixed changes which should not be flushed to disk and so should not +**** increase binlog_cache_disk_use. +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +begin; +insert into t1 values( 1 ); +insert into t2 values( 1 ); +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 5 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +drop table t1, t2; diff --git a/mysql-test/suite/binlog/r/binlog_stm_innodb_stat.result b/mysql-test/suite/binlog/r/binlog_stm_innodb_stat.result deleted file mode 100644 index 637be940383..00000000000 --- a/mysql-test/suite/binlog/r/binlog_stm_innodb_stat.result +++ /dev/null @@ -1,25 +0,0 @@ -flush status; -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 0 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 0 -drop table if exists t1; -create table t1 (a int) engine=innodb; -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 2 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 1 -begin; -delete from t1; -commit; -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 4 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 1 -drop table t1; diff --git a/mysql-test/suite/binlog/t/binlog_mix_innodb_stat.test b/mysql-test/suite/binlog/t/binlog_mixed_cache_stat.test similarity index 77% rename from mysql-test/suite/binlog/t/binlog_mix_innodb_stat.test rename to mysql-test/suite/binlog/t/binlog_mixed_cache_stat.test index 0be097c78ed..3e63fb3bc9c 100644 --- a/mysql-test/suite/binlog/t/binlog_mix_innodb_stat.test +++ b/mysql-test/suite/binlog/t/binlog_mixed_cache_stat.test @@ -2,4 +2,4 @@ # For both statement and row based bin logs 9/19/2005 [jbm] -- source include/have_binlog_format_mixed.inc --- source extra/binlog_tests/innodb_stat.test +-- source extra/binlog_tests/binlog_cache_stat.test diff --git a/mysql-test/suite/binlog/t/binlog_row_innodb_stat.test b/mysql-test/suite/binlog/t/binlog_row_cache_stat.test similarity index 77% rename from mysql-test/suite/binlog/t/binlog_row_innodb_stat.test rename to mysql-test/suite/binlog/t/binlog_row_cache_stat.test index e4e6762226b..03f9c53f0cc 100644 --- a/mysql-test/suite/binlog/t/binlog_row_innodb_stat.test +++ b/mysql-test/suite/binlog/t/binlog_row_cache_stat.test @@ -2,4 +2,4 @@ # For both statement and row based bin logs 9/19/2005 [jbm] -- source include/have_binlog_format_row.inc --- source extra/binlog_tests/innodb_stat.test +-- source extra/binlog_tests/binlog_cache_stat.test diff --git a/mysql-test/suite/binlog/t/binlog_stm_innodb_stat.test b/mysql-test/suite/binlog/t/binlog_stm_cache_stat.test similarity index 78% rename from mysql-test/suite/binlog/t/binlog_stm_innodb_stat.test rename to mysql-test/suite/binlog/t/binlog_stm_cache_stat.test index c6017246e6d..0f5aa9f6013 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_innodb_stat.test +++ b/mysql-test/suite/binlog/t/binlog_stm_cache_stat.test @@ -2,4 +2,4 @@ # For both statement and row based bin logs 9/19/2005 [jbm] -- source include/have_binlog_format_statement.inc --- source extra/binlog_tests/innodb_stat.test +-- source extra/binlog_tests/binlog_cache_stat.test diff --git a/sql/log.cc b/sql/log.cc index 8cf5dd9ae65..c037d3a58fa 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -210,6 +210,9 @@ class binlog_cache_data public: binlog_cache_data(): m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF), incident(FALSE), changes_to_non_trans_temp_table_flag(FALSE) +#ifndef DBUG_OFF + , has_trans(FALSE) +#endif { cache_log.end_of_file= max_binlog_cache_size; } @@ -262,6 +265,14 @@ public: incident= FALSE; before_stmt_pos= MY_OFF_T_UNDEF; cache_log.end_of_file= max_binlog_cache_size; + /* + When a truncate is called there may be write activity and by consequence + "disk_writes" is increased. This breaks the "disk_writes"' use by the + binary log which aims to compute the ratio between in-memory cache usage + and disk cache usage. To avoid this undesirable behavior, we reset the + variable after truncating the cache. + */ + cache_log.disk_writes= 0; DBUG_ASSERT(empty()); } @@ -292,6 +303,18 @@ public: before_stmt_pos= MY_OFF_T_UNDEF; } +#ifndef DBUG_OFF + bool is_transactional() + { + return(has_trans); + } + + void set_transactional(bool is_transactional) + { + has_trans= is_transactional; + } +#endif + /* Cache to store data before copying it to the binary log. */ @@ -321,6 +344,13 @@ private: */ bool changes_to_non_trans_temp_table_flag; +#ifndef DBUG_OFF + /* + Defines the type of the cache either: transactional or non-transactional. + */ + bool has_trans; +#endif + /* It truncates the cache to a certain position. This includes deleting the pending event. @@ -1506,56 +1536,146 @@ static int binlog_close_connection(handlerton *hton, THD *thd) } /** - This function flushes a transactional cache upon commit/rollback. + This function computes binlog cache and disk usage. - @param thd The thread whose transaction should be flushed - @param cache_mngr Pointer to the cache data to be flushed - @param end_ev The end event either commit/rollback. + @param cache_data Pointer to the cache where data is + stored. +*/ +static inline void +binlog_compute_statistics(binlog_cache_data* cache_data) +{ + if (!cache_data->empty()) + { + statistic_increment(binlog_cache_use, &LOCK_status); + if (cache_data->cache_log.disk_writes != 0) + statistic_increment(binlog_cache_disk_use, &LOCK_status); + } +} + +/** + This function flushes a cache upon commit/rollback. + + @param thd The thread whose transaction should be flushed + @param cache_data Pointer to the cache + @param end_ev The end event either commit/rollback + @param is_transactional The type of the cache: transactional or + non-transactional @return - nonzero if an error pops up when flushing the transactional cache. + nonzero if an error pops up when flushing the cache. */ -static int -binlog_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr, - Log_event *end_ev) +static inline int +binlog_flush_cache(THD *thd, binlog_cache_data* cache_data, Log_event *end_evt, + bool is_transactional) { - DBUG_ENTER("binlog_flush_trx_cache"); - int error=0; - IO_CACHE *cache_log= &cache_mngr->trx_cache.cache_log; + DBUG_ENTER("binlog_flush_cache"); + int error= 0; - /* - This function handles transactional changes and as such - this flag equals to true. - */ - bool const is_transactional= TRUE; - - if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional)) - DBUG_RETURN(1); - /* - Doing a commit or a rollback including non-transactional tables, - i.e., ending a transaction where we might write the transaction - cache to the binary log. - - We can always end the statement when ending a transaction since - transactions are not allowed inside stored functions. If they - were, we would have to ensure that we're not ending a statement - inside a stored function. - */ - error= mysql_bin_log.write(thd, &cache_mngr->trx_cache.cache_log, end_ev, - cache_mngr->trx_cache.has_incident()); - cache_mngr->reset_cache(&cache_mngr->trx_cache); - - statistic_increment(binlog_cache_use, &LOCK_status); - if (cache_log->disk_writes != 0) + if (!cache_data->empty()) { - statistic_increment(binlog_cache_disk_use, &LOCK_status); - cache_log->disk_writes= 0; - } +#ifndef DBUG_OFF + DBUG_PRINT("info", ("is_transactional(%d), event(%d), cache_data(%d)", + is_transactional, end_evt->use_trans_cache(), + cache_data->is_transactional())); + DBUG_ASSERT(is_transactional == end_evt->use_trans_cache() && + is_transactional == cache_data->is_transactional()); +#endif + if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional)) + DBUG_RETURN(1); + /* + Doing a commit or a rollback including non-transactional tables, + i.e., ending a transaction where we might write the transaction + cache to the binary log. - DBUG_ASSERT(cache_mngr->trx_cache.empty()); + We can always end the statement when ending a transaction since + transactions are not allowed inside stored functions. If they + were, we would have to ensure that we're not ending a statement + inside a stored function. + */ + error= mysql_bin_log.write(thd, &cache_data->cache_log, end_evt, + cache_data->has_incident()); + } + binlog_compute_statistics(cache_data); + cache_data->reset(); + + DBUG_ASSERT(cache_data->empty()); DBUG_RETURN(error); } +/** + This function flushes the stmt-cache upon commit. + + @param thd The thread whose transaction should be flushed + @param cache_mngr Pointer to the cache manager + + @return + nonzero if an error pops up when flushing the cache. +*/ +static inline int +binlog_commit_flush_stmt_cache(THD *thd, + binlog_cache_mngr *cache_mngr) +{ + Query_log_event end_evt(thd, STRING_WITH_LEN("COMMIT"), + FALSE, FALSE, TRUE, 0); + return (binlog_flush_cache(thd, &cache_mngr->stmt_cache, &end_evt, + FALSE)); +} + +/** + This function flushes the trx-cache upon commit. + + @param thd The thread whose transaction should be flushed + @param cache_mngr Pointer to the cache manager + + @return + nonzero if an error pops up when flushing the cache. +*/ +static inline int +binlog_commit_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr) +{ + Query_log_event end_evt(thd, STRING_WITH_LEN("COMMIT"), + TRUE, FALSE, TRUE, 0); + return (binlog_flush_cache(thd, &cache_mngr->trx_cache, &end_evt, + TRUE)); +} + +/** + This function flushes the trx-cache upon rollback. + + @param thd The thread whose transaction should be flushed + @param cache_mngr Pointer to the cache manager + + @return + nonzero if an error pops up when flushing the cache. +*/ +static inline int +binlog_rollback_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr) +{ + Query_log_event end_evt(thd, STRING_WITH_LEN("ROLLBACK"), + TRUE, FALSE, TRUE, 0); + return (binlog_flush_cache(thd, &cache_mngr->trx_cache, &end_evt, + TRUE)); +} + +/** + This function flushes the trx-cache upon commit. + + @param thd The thread whose transaction should be flushed + @param cache_mngr Pointer to the cache manager + @param xid Transaction Id + + @return + nonzero if an error pops up when flushing the cache. +*/ +static inline int +binlog_commit_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr, + my_xid xid) +{ + Xid_log_event end_evt(thd, xid); + return (binlog_flush_cache(thd, &cache_mngr->trx_cache, &end_evt, + TRUE)); +} + /** This function truncates the transactional cache upon committing or rolling back either a transaction or a statement. @@ -1579,23 +1699,26 @@ binlog_truncate_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr, bool all) */ bool const is_transactional= TRUE; - DBUG_PRINT("info", ("thd->options={ %s%s}, transaction: %s", + DBUG_PRINT("info", ("thd->options={ %s %s}, transaction: %s", FLAGSTR(thd->variables.option_bits, OPTION_NOT_AUTOCOMMIT), FLAGSTR(thd->variables.option_bits, OPTION_BEGIN), all ? "all" : "stmt")); + + thd->binlog_remove_pending_rows_event(TRUE, is_transactional); /* If rolling back an entire transaction or a single statement not inside a transaction, we reset the transaction cache. */ - thd->binlog_remove_pending_rows_event(TRUE, is_transactional); if (ending_trans(thd, all)) { if (cache_mngr->trx_cache.has_incident()) error= mysql_bin_log.write_incident(thd, TRUE); - cache_mngr->reset_cache(&cache_mngr->trx_cache); - thd->clear_binlog_table_maps(); + + binlog_compute_statistics(&cache_mngr->trx_cache); + + cache_mngr->reset_cache(&cache_mngr->trx_cache); } /* If rolling back a statement in a transaction, we truncate the @@ -1619,51 +1742,6 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all) return 0; } -/** - This function flushes the non-transactional to the binary log upon - committing or rolling back a statement. - - @param thd The thread whose transaction should be flushed - @param cache_mngr Pointer to the cache data to be flushed - - @return - nonzero if an error pops up when flushing the non-transactional cache. -*/ -static int -binlog_flush_stmt_cache(THD *thd, binlog_cache_mngr *cache_mngr) -{ - int error= 0; - DBUG_ENTER("binlog_flush_stmt_cache"); - /* - If we are flushing the statement cache, it means that the changes get - through otherwise the cache is empty and this routine should not be called. - */ - DBUG_ASSERT(cache_mngr->stmt_cache.has_incident() == FALSE); - /* - This function handles non-transactional changes and as such this flag equals - to false. - */ - bool const is_transactional= FALSE; - IO_CACHE *cache_log= &cache_mngr->stmt_cache.cache_log; - - if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional)) - DBUG_RETURN(1); - - Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE, TRUE, 0); - if ((error= mysql_bin_log.write(thd, cache_log, &qev, - cache_mngr->stmt_cache.has_incident()))) - DBUG_RETURN(error); - cache_mngr->reset_cache(&cache_mngr->stmt_cache); - - statistic_increment(binlog_cache_use, &LOCK_status); - if (cache_log->disk_writes != 0) - { - statistic_increment(binlog_cache_disk_use, &LOCK_status); - cache_log->disk_writes= 0; - } - DBUG_RETURN(error); -} - /** This function is called once after each statement. @@ -1690,19 +1768,7 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) YESNO(thd->transaction.all.modified_non_trans_table), YESNO(thd->transaction.stmt.modified_non_trans_table))); - if (!cache_mngr->stmt_cache.empty()) - { - binlog_flush_stmt_cache(thd, cache_mngr); - } - - if (cache_mngr->trx_cache.empty()) - { - /* - we're here because cache_log was flushed in MYSQL_BIN_LOG::log_xid() - */ - cache_mngr->reset_cache(&cache_mngr->trx_cache); - DBUG_RETURN(0); - } + binlog_commit_flush_stmt_cache(thd, cache_mngr); /* We commit the transaction if: @@ -1711,16 +1777,14 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) Otherwise, we accumulate the changes. */ if (ending_trans(thd, all)) - { - Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE, TRUE, 0); - error= binlog_flush_trx_cache(thd, cache_mngr, &qev); - } + error= binlog_commit_flush_trx_cache(thd, cache_mngr); /* This is part of the stmt rollback. */ if (!all) cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF); + DBUG_RETURN(error); } @@ -1755,19 +1819,8 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) error= mysql_bin_log.write_incident(thd, TRUE); cache_mngr->reset_cache(&cache_mngr->stmt_cache); } - else if (!cache_mngr->stmt_cache.empty()) - { - binlog_flush_stmt_cache(thd, cache_mngr); - } - - if (cache_mngr->trx_cache.empty()) - { - /* - we're here because cache_log was flushed in MYSQL_BIN_LOG::log_xid() - */ - cache_mngr->reset_cache(&cache_mngr->trx_cache); - DBUG_RETURN(0); - } + else + binlog_commit_flush_stmt_cache(thd, cache_mngr); if (mysql_bin_log.check_write_error(thd)) { @@ -1796,7 +1849,6 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) . the format is MIXED, non-trans table was updated and aborting a single statement transaction; */ - if (ending_trans(thd, all) && ((thd->variables.option_bits & OPTION_KEEP_LOG) || (trans_has_updated_non_trans_table(thd) && @@ -1806,10 +1858,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) (trans_has_updated_non_trans_table(thd) && ending_single_stmt_trans(thd,all) && thd->variables.binlog_format == BINLOG_FORMAT_MIXED))) - { - Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE, TRUE, 0); - error= binlog_flush_trx_cache(thd, cache_mngr, &qev); - } + error= binlog_rollback_flush_trx_cache(thd, cache_mngr); /* Truncate the cache if: . aborting a single or multi-statement transaction or; @@ -1832,7 +1881,8 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) This is part of the stmt rollback. */ if (!all) - cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF); + cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF); + DBUG_RETURN(error); } @@ -4364,6 +4414,11 @@ int THD::binlog_setup_trx_data() cache_mngr= new (thd_get_ha_data(this, binlog_hton)) binlog_cache_mngr; +#ifndef DBUG_OFF + cache_mngr->trx_cache.set_transactional(TRUE); + cache_mngr->stmt_cache.set_transactional(FALSE); +#endif + DBUG_RETURN(0); } @@ -6291,15 +6346,14 @@ void TC_LOG_BINLOG::close() int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid) { DBUG_ENTER("TC_LOG_BINLOG::log"); - Xid_log_event xle(thd, xid); binlog_cache_mngr *cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); /* We always commit the entire transaction when writing an XID. Also note that the return value is inverted. */ - DBUG_RETURN(!binlog_flush_stmt_cache(thd, cache_mngr) && - !binlog_flush_trx_cache(thd, cache_mngr, &xle)); + DBUG_RETURN(!binlog_commit_flush_stmt_cache(thd, cache_mngr) && + !binlog_commit_flush_trx_cache(thd, cache_mngr, xid)); } void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid) diff --git a/sql/log_event.cc b/sql/log_event.cc index 16290c58685..560d6ffa502 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2537,6 +2537,22 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, bool trx_cache= FALSE; cache_type= Log_event::EVENT_INVALID_CACHE; +#ifndef DBUG_OFF + /* + If debug is enabled, we make sure that begin, commit and rollback + have the cache_type exclusively defined by the param using_trans. + as this is important while checking if the correct cache is used. + + Note this is the only way to accurately set the type of the cache + when a begin, commit or rollback event is created because such + events may be artificially produced to compose the binary log. + */ + if (strncmp("BEGIN", query_arg, query_length) && + strncmp("COMMIT", query_arg, query_length) && + strncmp("ROLLBACK", query_arg, query_length)) + { +#endif + switch (lex->sql_command) { case SQLCOM_DROP_TABLE: @@ -2574,6 +2590,15 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE; else cache_type= Log_event::EVENT_STMT_CACHE; + +#ifndef DBUG_OFF + } + else if (using_trans) + cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE; + else + cache_type= Log_event::EVENT_STMT_CACHE; +#endif + DBUG_ASSERT(cache_type != Log_event::EVENT_INVALID_CACHE); DBUG_PRINT("info",("Query_log_event has flags2: %lu sql_mode: %lu", (ulong) flags2, sql_mode)); diff --git a/sql/log_event.h b/sql/log_event.h index 5d7250d8ebd..e2baffdb9b1 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -2504,7 +2504,7 @@ class Xid_log_event: public Log_event my_xid xid; #ifdef MYSQL_SERVER - Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg,0,0), xid(x) {} + Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg, 0, TRUE), xid(x) {} #ifdef HAVE_REPLICATION void pack_info(Protocol* protocol); #endif /* HAVE_REPLICATION */ From 07fd5d6f993992f04074c6d16e08cdf42d22cc97 Mon Sep 17 00:00:00 2001 From: Oystein Grovlen Date: Wed, 20 Oct 2010 15:17:29 +0200 Subject: [PATCH 002/110] 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 | 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 95ee8f4cf61d9be85f1df6805a058fa11b6de04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Bl=C3=A5udd?= Date: Wed, 20 Oct 2010 15:54:58 +0200 Subject: [PATCH 003/110] Bug#57604 Reserve bit in option_bits for slave_allow_batching feature - Add define to reserve bit number 36 for slave_allow_batching feature --- sql/sql_priv.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sql/sql_priv.h b/sql/sql_priv.h index f0f6a1969f5..4e1dac269b7 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -144,6 +144,12 @@ */ #define OPTION_MASTER_SQL_ERROR (1ULL << 35) +/* + Dont report errors for individual rows, + But just report error on commit (or read ofcourse) + Note! Reserved for use in MySQL Cluster +*/ +#define OPTION_ALLOW_BATCH (ULL(1) << 36) // THD, intern (slave) /* The rest of the file is included in the server only */ #ifndef MYSQL_CLIENT From 32af78c593a734985ff0c5c7e5cf9fec781a27dd Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 27 Oct 2010 23:59:07 +0200 Subject: [PATCH 004/110] 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 6c8163ddffd5906ee3fdc50d71baccc8805dfe91 Mon Sep 17 00:00:00 2001 From: "kevin.lewis@oracle.com" <> Date: Tue, 2 Nov 2010 10:16:55 -0500 Subject: [PATCH 005/110] 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 fb9c58860322675cddd83efcd96e52c514f1e021 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 2 Nov 2010 22:32:29 +0100 Subject: [PATCH 006/110] 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 bf2c66d4a7281c1d7dbf49cbad315c7041762670 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Fri, 5 Nov 2010 17:42:37 +0000 Subject: [PATCH 007/110] BUG#57275 binlog_cache_size affects trx- and stmt-cache and gets twice the expected memory After the WL#2687, the binlog_cache_size and max_binlog_cache_size affect both the stmt-cache and the trx-cache. This means that the resource used is twice the amount expected/defined by the user. The binlog_cache_use is incremented when the stmt-cache or the trx-cache is used and binlog_cache_disk_use is incremented when the disk space from the stmt-cache or the trx-cache is used. This behavior does not allow to distinguish which cache may be harming performance due to the extra disk accesses and needs to have its in-memory cache increased. To fix the problem, we introduced two new options and status variables related to the stmt-cache: Options: . binlog_stmt_cache_size . max_binlog_stmt_cache_size Status Variables: . binlog_stmt_cache_use . binlog_stmt_cache_disk_use So there are . binlog_cache_size that defines the size of the transactional cache for updates to transactional engines for the binary log. . binlog_stmt_cache_size that defines the size of the statement cache for updates to non-transactional engines for the binary log. . max_binlog_cache_size that sets the total size of the transactional cache. . max_binlog_stmt_cache_size that sets the total size of the statement cache. . binlog_cache_use that identifies the number of transactions that used the temporary transactional binary log cache. . binlog_cache_disk_use that identifies the number of transactions that used the temporary transactional binary log cache but that exceeded the value of binlog_cache_size. . binlog_stmt_cache_use that identifies the number of statements that used the temporary non-transactional binary log cache. . binlog_stmt_cache_disk_use that identifies the number of statements that used the temporary non-transactional binary log cache but that exceeded the value of binlog_stmt_cache_size. --- include/my_sys.h | 3 +- .../extra/binlog_tests/binlog_cache_stat.test | 184 ++++++++++++------ .../rpl_tests/rpl_binlog_max_cache_size.test | 69 ++++--- mysql-test/r/mysqld--help-notwin.result | 20 +- .../binlog/r/binlog_mixed_cache_stat.result | 42 ++-- .../binlog/r/binlog_row_cache_stat.result | 42 ++-- .../binlog/r/binlog_stm_cache_stat.result | 42 ++-- .../r/rpl_mixed_binlog_max_cache_size.result | 9 + .../r/rpl_row_binlog_max_cache_size.result | 9 + .../r/rpl_stm_binlog_max_cache_size.result | 9 + .../inc/binlog_stmt_cache_size_basic.inc | 154 +++++++++++++++ .../r/binlog_stmt_cache_size_basic_32.result | 108 ++++++++++ .../r/binlog_stmt_cache_size_basic_64.result | 108 ++++++++++ .../r/max_binlog_stmt_cache_size_basic.result | 152 +++++++++++++++ .../t/binlog_stmt_cache_size_basic_32.test | 7 + .../t/binlog_stmt_cache_size_basic_64.test | 7 + .../t/max_binlog_cache_size_func-master.opt | 2 - .../t/max_binlog_stmt_cache_size_basic.test | 184 ++++++++++++++++++ sql/log.cc | 122 +++++++++--- sql/log.h | 2 +- sql/mysqld.cc | 5 + sql/mysqld.h | 6 +- sql/share/errmsg-utf8.txt | 2 + sql/sys_vars.cc | 28 ++- 24 files changed, 1130 insertions(+), 186 deletions(-) create mode 100644 mysql-test/suite/sys_vars/inc/binlog_stmt_cache_size_basic.inc create mode 100644 mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_32.result create mode 100644 mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_64.result create mode 100644 mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result create mode 100644 mysql-test/suite/sys_vars/t/binlog_stmt_cache_size_basic_32.test create mode 100644 mysql-test/suite/sys_vars/t/binlog_stmt_cache_size_basic_64.test delete mode 100644 mysql-test/suite/sys_vars/t/max_binlog_cache_size_func-master.opt create mode 100644 mysql-test/suite/sys_vars/t/max_binlog_stmt_cache_size_basic.test diff --git a/include/my_sys.h b/include/my_sys.h index 23c9b2da55f..c50f014b88c 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -456,7 +456,8 @@ typedef struct st_io_cache /* Used when cacheing files */ IO_CACHE_CALLBACK pre_close; /* Counts the number of times, when we were forced to use disk. We use it to - increase the binlog_cache_disk_use status variable. + increase the binlog_cache_disk_use and binlog_stmt_cache_disk_use status + variables. */ ulong disk_writes; void* arg; /* for use by pre/post_read */ diff --git a/mysql-test/extra/binlog_tests/binlog_cache_stat.test b/mysql-test/extra/binlog_tests/binlog_cache_stat.test index f82bc9c40b4..a602b098201 100644 --- a/mysql-test/extra/binlog_tests/binlog_cache_stat.test +++ b/mysql-test/extra/binlog_tests/binlog_cache_stat.test @@ -18,23 +18,28 @@ create table t2 (a int) engine=myisam; # # Checking commit. # ---echo **** Preparing the enviroment to check commit and its effect on ---echo **** the binlog_cache_use and binlog_cache_disk_use. +--echo **** Preparing the enviroment to check commit and its effect on status variables. --echo **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +--echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. flush status; let $exp_cache= 0; let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); let $exp_disk= 0; let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); -if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk`) +let $exp_stmt_cache= 0; +let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); +let $exp_stmt_disk= 0; +let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); +if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk || $got_stmt_cache <> $exp_stmt_cache || $got_stmt_disk <> $exp_stmt_disk`) { - -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk but" + -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk" + -- echo "Expected: binlog_stmt_cache_use = $exp_stmt_cache, binlog_stmt_cache_disk_use = $exp_stmt_disk but got binlog_stmt_cache_use = $got_stmt_cache, binlog_stmt_cache_disk_use = $got_stmt_disk" -- die } ---echo **** Now we are going to create transactional changes which are long enough so ---echo **** they will be flushed to disk... +--echo **** Transactional changes which are long enough so they will be flushed to disk... --echo **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +--echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. let $1=2000; disable_query_log; begin; @@ -49,15 +54,21 @@ let $exp_cache= 1; let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); let $exp_disk= 1; let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); -if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk`) +let $exp_stmt_cache= 0; +let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); +let $exp_stmt_disk= 0; +let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); +if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk || $got_stmt_cache <> $exp_stmt_cache || $got_stmt_disk <> $exp_stmt_disk`) { - -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk but" + -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk" + -- echo "Expected: binlog_stmt_cache_use = $exp_stmt_cache, binlog_stmt_cache_disk_use = $exp_stmt_disk but got binlog_stmt_cache_use = $got_stmt_cache, binlog_stmt_cache_disk_use = $got_stmt_disk" -- die } --echo **** Transactional changes which should not be flushed to disk and so should not ---echo **** increase binlog_cache_disk_use. +--echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. --echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +--echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); commit; @@ -65,65 +76,87 @@ let $exp_cache= 2; let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); let $exp_disk= 1; let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); -if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk`) +let $exp_stmt_cache= 0; +let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); +let $exp_stmt_disk= 0; +let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); +if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk || $got_stmt_cache <> $exp_stmt_cache || $got_stmt_disk <> $exp_stmt_disk`) { - -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk but" + -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk" + -- echo "Expected: binlog_stmt_cache_use = $exp_stmt_cache, binlog_stmt_cache_disk_use = $exp_stmt_disk but got binlog_stmt_cache_use = $got_stmt_cache, binlog_stmt_cache_disk_use = $got_stmt_disk" -- die } --echo **** Non-Transactional changes which should not be flushed to disk and so should not ---echo **** increase binlog_cache_disk_use. ---echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +--echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +--echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. begin; insert into t2 values( 1 ); commit; +let $exp_cache= 2; +let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); +let $exp_disk= 1; +let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); +let $exp_stmt_cache= 1; +let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); +let $exp_stmt_disk= 0; +let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); +if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk || $got_stmt_cache <> $exp_stmt_cache || $got_stmt_disk <> $exp_stmt_disk`) +{ + -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk" + -- echo "Expected: binlog_stmt_cache_use = $exp_stmt_cache, binlog_stmt_cache_disk_use = $exp_stmt_disk but got binlog_stmt_cache_use = $got_stmt_cache, binlog_stmt_cache_disk_use = $got_stmt_disk" + -- die +} + +--echo **** Mixed changes which should not be flushed to disk and so should not +--echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +--echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +--echo **** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. +begin; +insert into t1 values( 1 ); +insert into t2 values( 1 ); +commit; let $exp_cache= 3; let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); let $exp_disk= 1; let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); -if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk`) +let $exp_stmt_cache= 2; +let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); +let $exp_stmt_disk= 0; +let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); +if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk || $got_stmt_cache <> $exp_stmt_cache || $got_stmt_disk <> $exp_stmt_disk`) { - -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk but" - -- die -} - ---echo **** Mixed changes which should not be flushed to disk and so should not ---echo **** increase binlog_cache_disk_use. ---echo **** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. -begin; -insert into t1 values( 1 ); -insert into t2 values( 1 ); -commit; -let $exp_cache= 5; -let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); -let $exp_disk= 1; -let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); -if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk`) -{ - -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk but" + -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk" + -- echo "Expected: binlog_stmt_cache_use = $exp_stmt_cache, binlog_stmt_cache_disk_use = $exp_stmt_disk but got binlog_stmt_cache_use = $got_stmt_cache, binlog_stmt_cache_disk_use = $got_stmt_disk" -- die } # # Checking abort. # ---echo **** Preparing the enviroment to check abort and its effect on ---echo **** the binlog_cache_use and binlog_cache_disk_use +--echo **** Preparing the enviroment to check abort and its effect on the status variables. --echo **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +--echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. flush status; let $exp_cache= 0; let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); let $exp_disk= 0; let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); -if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk`) +let $exp_stmt_cache= 0; +let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); +let $exp_stmt_disk= 0; +let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); +if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk || $got_stmt_cache <> $exp_stmt_cache || $got_stmt_disk <> $exp_stmt_disk`) { - -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk but" + -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk" + -- echo "Expected: binlog_stmt_cache_use = $exp_stmt_cache, binlog_stmt_cache_disk_use = $exp_stmt_disk but got binlog_stmt_cache_use = $got_stmt_cache, binlog_stmt_cache_disk_use = $got_stmt_disk" -- die } ---echo **** Now we are going to create transactional changes which are long enough so ---echo **** they will be flushed to disk... +--echo **** Transactional changes which are long enough so they will be flushed to disk... --echo **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +--echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. let $1=2000; disable_query_log; begin; @@ -138,15 +171,21 @@ let $exp_cache= 1; let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); let $exp_disk= 1; let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); -if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk`) +let $exp_stmt_cache= 0; +let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); +let $exp_stmt_disk= 0; +let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); +if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk || $got_stmt_cache <> $exp_stmt_cache || $got_stmt_disk <> $exp_stmt_disk`) { - -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk but" + -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk" + -- echo "Expected: binlog_stmt_cache_use = $exp_stmt_cache, binlog_stmt_cache_disk_use = $exp_stmt_disk but got binlog_stmt_cache_use = $got_stmt_cache, binlog_stmt_cache_disk_use = $got_stmt_disk" -- die } --echo **** Transactional changes which should not be flushed to disk and so should not ---echo **** increase binlog_cache_disk_use. +--echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. --echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +--echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); rollback; @@ -154,42 +193,59 @@ let $exp_cache= 2; let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); let $exp_disk= 1; let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); -if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk`) +let $exp_stmt_cache= 0; +let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); +let $exp_stmt_disk= 0; +let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); +if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk || $got_stmt_cache <> $exp_stmt_cache || $got_stmt_disk <> $exp_stmt_disk`) { - -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk but" + -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk" + -- echo "Expected: binlog_stmt_cache_use = $exp_stmt_cache, binlog_stmt_cache_disk_use = $exp_stmt_disk but got binlog_stmt_cache_use = $got_stmt_cache, binlog_stmt_cache_disk_use = $got_stmt_disk" -- die } --echo **** Non-Transactional changes which should not be flushed to disk and so should not ---echo **** increase binlog_cache_disk_use. ---echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +--echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +--echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. begin; insert into t2 values( 1 ); rollback; +let $exp_cache= 2; +let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); +let $exp_disk= 1; +let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); +let $exp_stmt_cache= 1; +let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); +let $exp_stmt_disk= 0; +let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); +if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk || $got_stmt_cache <> $exp_stmt_cache || $got_stmt_disk <> $exp_stmt_disk`) +{ + -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk" + -- echo "Expected: binlog_stmt_cache_use = $exp_stmt_cache, binlog_stmt_cache_disk_use = $exp_stmt_disk but got binlog_stmt_cache_use = $got_stmt_cache, binlog_stmt_cache_disk_use = $got_stmt_disk" + -- die +} + +--echo **** Mixed changes which should not be flushed to disk and so should not +--echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +--echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +--echo **** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. +begin; +insert into t1 values( 1 ); +insert into t2 values( 1 ); +rollback; let $exp_cache= 3; let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); let $exp_disk= 1; let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); -if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk`) +let $exp_stmt_cache= 2; +let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); +let $exp_stmt_disk= 0; +let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); +if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk || $got_stmt_cache <> $exp_stmt_cache || $got_stmt_disk <> $exp_stmt_disk`) { - -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk but" - -- die -} - ---echo **** Mixed changes which should not be flushed to disk and so should not ---echo **** increase binlog_cache_disk_use. ---echo **** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. -begin; -insert into t1 values( 1 ); -insert into t2 values( 1 ); -rollback; -let $exp_cache= 5; -let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); -let $exp_disk= 1; -let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); -if (`SELECT $got_cache <> $exp_cache || $got_disk <> $exp_disk`) -{ - -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk but" + -- echo "Expected: binlog_cache_use = $exp_cache, binlog_cache_disk_use = $exp_disk but got binlog_cache_use = $got_cache, binlog_cache_disk_use = $got_disk" + -- echo "Expected: binlog_stmt_cache_use = $exp_stmt_cache, binlog_stmt_cache_disk_use = $exp_stmt_disk but got binlog_stmt_cache_use = $got_stmt_cache, binlog_stmt_cache_disk_use = $got_stmt_disk" -- die } drop table t1, t2; diff --git a/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test b/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test index 3d97ad10d17..385a82baa77 100644 --- a/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test +++ b/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test @@ -25,11 +25,13 @@ call mtr.add_suppression("Unsafe statement written to the binary log using state let $old_max_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "max_binlog_cache_size", Value, 1); let $old_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "binlog_cache_size", Value, 1); +let $old_max_binlog_stmt_cache_size= query_get_value(SHOW VARIABLES LIKE "max_binlog_stmt_cache_size", Value, 1); +let $old_binlog_stmt_cache_size= query_get_value(SHOW VARIABLES LIKE "binlog_stmt_cache_size", Value, 1); SET GLOBAL max_binlog_cache_size = 4096; -# Becuase of bug#55377, we have to set binlog_cache_size until the bug is -# fixed. SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; disconnect master; connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); @@ -47,14 +49,14 @@ connection master; --echo *** Single statement on transactional table *** --disable_query_log ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE eval INSERT INTO t1 (a, data) VALUES (1, CONCAT($data, $data, $data, $data, $data)); --enable_query_log --echo *** Single statement on non-transactional table *** --disable_query_log ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE eval INSERT INTO t2 (a, data) VALUES (2, CONCAT($data, $data, $data, $data, $data, $data)); --enable_query_log @@ -74,7 +76,7 @@ eval INSERT INTO t2 (a, data) VALUES (5, $data); --echo *** Single statement on both transactional and non-transactional tables. *** --disable_query_log ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE eval UPDATE t2, t1 SET t2.data = CONCAT($data, $data, $data, $data), t1.data = CONCAT($data, $data, $data, $data); --enable_query_log @@ -103,11 +105,11 @@ BEGIN; --eval INSERT INTO t1 (a, data) VALUES (1, $data); --eval INSERT INTO t1 (a, data) VALUES (2, $data); --eval INSERT INTO t1 (a, data) VALUES (3, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (4, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (5, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (6, $data); --eval INSERT INTO t1 (a, data) VALUES (7, 's'); --eval INSERT INTO t2 (a, data) VALUES (8, 's'); @@ -130,9 +132,9 @@ BEGIN; --eval INSERT INTO t1 (a, data) VALUES (14, $data); --eval INSERT INTO t1 (a, data) VALUES (15, $data); --eval INSERT INTO t1 (a, data) VALUES (16, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (17, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (18, $data); --eval INSERT INTO t1 (a, data) VALUES (19, 's'); --eval INSERT INTO t2 (a, data) VALUES (20, 's'); @@ -148,7 +150,7 @@ if (`SELECT @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`) if (`SELECT @@binlog_format = 'ROW'`) { --disable_query_log - --error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE + --error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE CREATE TABLE t4 SELECT * FROM t1; --enable_query_log } @@ -162,9 +164,9 @@ BEGIN; --eval INSERT INTO t1 (a, data) VALUES (22, $data); --eval INSERT INTO t1 (a, data) VALUES (23, $data); --eval INSERT INTO t1 (a, data) VALUES (24, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (25, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (26, $data); --eval INSERT INTO t1 (a, data) VALUES (27, 's'); --eval INSERT INTO t2 (a, data) VALUES (28, 's'); @@ -192,11 +194,11 @@ BEGIN; --eval INSERT INTO t1 (a, data) VALUES (1, $data); --eval INSERT INTO t1 (a, data) VALUES (2, $data); --eval INSERT INTO t1 (a, data) VALUES (3, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (4, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (5, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (6, $data); --eval INSERT INTO t1 (a, data) VALUES (7, 's'); --eval INSERT INTO t2 (a, data) VALUES (8, 's'); @@ -221,11 +223,11 @@ BEGIN; --eval INSERT INTO t1 (a, data) VALUES (1, $data); --eval INSERT INTO t1 (a, data) VALUES (2, $data); --eval INSERT INTO t1 (a, data) VALUES (3, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (4, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (5, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (6, $data); --eval INSERT INTO t1 (a, data) VALUES (7, 's'); --eval INSERT INTO t2 (a, data) VALUES (8, 's'); @@ -268,7 +270,7 @@ TRUNCATE TABLE t1; BEGIN; --disable_query_log ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE eval CALL p1($data); --enable_query_log COMMIT; @@ -277,7 +279,7 @@ TRUNCATE TABLE t1; BEGIN; --disable_query_log ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE eval CALL p1($data); --enable_query_log ROLLBACK; @@ -299,12 +301,12 @@ BEGIN; --eval INSERT INTO t1 (a, data) VALUES (1, $data); --eval INSERT INTO t1 (a, data) VALUES (2, $data); --eval INSERT INTO t1 (a, data) VALUES (3, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (4, $data); SAVEPOINT sv; ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (5, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (6, $data); --eval INSERT INTO t1 (a, data) VALUES (7, 's'); --eval INSERT INTO t2 (a, data) VALUES (8, 's'); @@ -331,11 +333,11 @@ BEGIN; --eval INSERT INTO t1 (a, data) VALUES (2, $data); --eval INSERT INTO t2 (a, data) VALUES (3, $data); --eval INSERT INTO t1 (a, data) VALUES (4, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (5, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (6, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (7, $data); --eval UPDATE t2 SET data= CONCAT($data, $data); --eval INSERT INTO t1 (a, data) VALUES (8, 's'); @@ -351,7 +353,7 @@ BEGIN; --eval INSERT INTO t1 (a, data) VALUES (16, $data); --eval INSERT INTO t2 (a, data) VALUES (17, $data); --eval INSERT INTO t1 (a, data) VALUES (18, $data); ---error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE --eval INSERT INTO t1 (a, data) VALUES (19, $data); --enable_query_log COMMIT; @@ -367,10 +369,13 @@ let $diff_statement= SELECT * FROM t1; --echo # [ On Slave ] SET GLOBAL max_binlog_cache_size = 4096; SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; source include/stop_slave.inc; source include/start_slave.inc; CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_stmt_cache_size' bytes of storage.*"); CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); connection master; @@ -385,6 +390,10 @@ connection master; --eval SET GLOBAL max_binlog_cache_size= $old_max_binlog_cache_size --replace_result $old_binlog_cache_size ORIGINAL_VALUE --eval SET GLOBAL binlog_cache_size= $old_binlog_cache_size +--replace_result $old_max_binlog_stmt_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_stmt_cache_size= $old_max_binlog_stmt_cache_size +--replace_result $old_binlog_stmt_cache_size ORIGINAL_VALUE +--eval SET GLOBAL binlog_stmt_cache_size= $old_binlog_stmt_cache_size disconnect master; connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); @@ -415,6 +424,10 @@ source include/show_binlog_events.inc; --eval SET GLOBAL max_binlog_cache_size= $old_max_binlog_cache_size --replace_result $old_binlog_cache_size ORIGINAL_VALUE --eval SET GLOBAL binlog_cache_size= $old_binlog_cache_size +--replace_result $old_max_binlog_stmt_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_stmt_cache_size= $old_max_binlog_stmt_cache_size +--replace_result $old_binlog_stmt_cache_size ORIGINAL_VALUE +--eval SET GLOBAL binlog_stmt_cache_size= $old_binlog_stmt_cache_size source include/stop_slave.inc; source include/start_slave.inc; diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result index 63e17e1c188..2d2a3cb919a 100644 --- a/mysql-test/r/mysqld--help-notwin.result +++ b/mysql-test/r/mysqld--help-notwin.result @@ -31,10 +31,10 @@ The following options may be given as the first argument: file (Solves most 'table full' errors) --bind-address=name IP address to bind to. --binlog-cache-size=# - The size of the cache to hold the SQL statements for the - binary log during a transaction. If you often use big, - multi-statement transactions you can increase this to get - more performance + The size of the transactional cache for updates to + transactional engines for the binary log. If you often + use transactions containing many statements, you can + increase this to get more performance --binlog-direct-non-transactional-updates Causes updates to non-transactional engines using statement format to be written directly to binary log. @@ -65,6 +65,11 @@ The following options may be given as the first argument: The maximum size of a row-based binary log event in bytes. Rows will be grouped into events smaller than this size if possible. The value has to be a multiple of 256. + --binlog-stmt-cache-size=# + The size of the statement cache for updates to + non-transactional engines for the binary log. If you + often use statements updating a great number of rows, you + can increase this to get more performance --bootstrap Used by mysql installation scripts. --bulk-insert-buffer-size=# Size of tree cache used in bulk insert optimisation. Note @@ -277,14 +282,15 @@ The following options may be given as the first argument: --max-allowed-packet=# Max packet length to send to or receive from the server --max-binlog-cache-size=# - Can be used to restrict the total size used to cache a - multi-transaction query + Sets the total size of the transactional cache --max-binlog-dump-events=# Option used by mysql-test for debugging and testing of replication. --max-binlog-size=# Binary log will be rotated automatically when the size exceeds this value. Will also apply to relay logs if max_relay_log_size is 0 + --max-binlog-stmt-cache-size=# + Sets the total size of the statement cache --max-connect-errors=# If there is more than this number of interrupted connections from a host this host will be blocked from @@ -733,6 +739,7 @@ binlog-cache-size 32768 binlog-direct-non-transactional-updates FALSE binlog-format STATEMENT binlog-row-event-max-size 1024 +binlog-stmt-cache-size 32768 bulk-insert-buffer-size 8388608 character-set-client-handshake TRUE character-set-filesystem binary @@ -812,6 +819,7 @@ max-allowed-packet 1048576 max-binlog-cache-size 18446744073709547520 max-binlog-dump-events 0 max-binlog-size 1073741824 +max-binlog-stmt-cache-size 18446744073709547520 max-connect-errors 10 max-connections 151 max-delayed-threads 20 diff --git a/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result b/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result index e9c344e4f7d..09cdab8414a 100644 --- a/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result +++ b/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result @@ -1,56 +1,62 @@ drop table if exists t1, t2; create table t1 (a int) engine=innodb; create table t2 (a int) engine=myisam; -**** Preparing the enviroment to check commit and its effect on -**** the binlog_cache_use and binlog_cache_disk_use. +**** Preparing the enviroment to check commit and its effect on status variables. **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. flush status; -**** Now we are going to create transactional changes which are long enough so -**** they will be flushed to disk... +**** Transactional changes which are long enough so they will be flushed to disk... **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. **** Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); commit; **** Non-Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. begin; insert into t2 values( 1 ); commit; **** Mixed changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); insert into t2 values( 1 ); commit; -**** Preparing the enviroment to check abort and its effect on -**** the binlog_cache_use and binlog_cache_disk_use +**** Preparing the enviroment to check abort and its effect on the status variables. **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. flush status; -**** Now we are going to create transactional changes which are long enough so -**** they will be flushed to disk... +**** Transactional changes which are long enough so they will be flushed to disk... **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. **** Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); rollback; **** Non-Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. begin; insert into t2 values( 1 ); rollback; Warnings: Warning 1196 Some non-transactional changed tables couldn't be rolled back **** Mixed changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); insert into t2 values( 1 ); diff --git a/mysql-test/suite/binlog/r/binlog_row_cache_stat.result b/mysql-test/suite/binlog/r/binlog_row_cache_stat.result index e9c344e4f7d..09cdab8414a 100644 --- a/mysql-test/suite/binlog/r/binlog_row_cache_stat.result +++ b/mysql-test/suite/binlog/r/binlog_row_cache_stat.result @@ -1,56 +1,62 @@ drop table if exists t1, t2; create table t1 (a int) engine=innodb; create table t2 (a int) engine=myisam; -**** Preparing the enviroment to check commit and its effect on -**** the binlog_cache_use and binlog_cache_disk_use. +**** Preparing the enviroment to check commit and its effect on status variables. **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. flush status; -**** Now we are going to create transactional changes which are long enough so -**** they will be flushed to disk... +**** Transactional changes which are long enough so they will be flushed to disk... **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. **** Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); commit; **** Non-Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. begin; insert into t2 values( 1 ); commit; **** Mixed changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); insert into t2 values( 1 ); commit; -**** Preparing the enviroment to check abort and its effect on -**** the binlog_cache_use and binlog_cache_disk_use +**** Preparing the enviroment to check abort and its effect on the status variables. **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. flush status; -**** Now we are going to create transactional changes which are long enough so -**** they will be flushed to disk... +**** Transactional changes which are long enough so they will be flushed to disk... **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. **** Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); rollback; **** Non-Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. begin; insert into t2 values( 1 ); rollback; Warnings: Warning 1196 Some non-transactional changed tables couldn't be rolled back **** Mixed changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); insert into t2 values( 1 ); diff --git a/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result b/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result index e9c344e4f7d..09cdab8414a 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result +++ b/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result @@ -1,56 +1,62 @@ drop table if exists t1, t2; create table t1 (a int) engine=innodb; create table t2 (a int) engine=myisam; -**** Preparing the enviroment to check commit and its effect on -**** the binlog_cache_use and binlog_cache_disk_use. +**** Preparing the enviroment to check commit and its effect on status variables. **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. flush status; -**** Now we are going to create transactional changes which are long enough so -**** they will be flushed to disk... +**** Transactional changes which are long enough so they will be flushed to disk... **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. **** Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); commit; **** Non-Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. begin; insert into t2 values( 1 ); commit; **** Mixed changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); insert into t2 values( 1 ); commit; -**** Preparing the enviroment to check abort and its effect on -**** the binlog_cache_use and binlog_cache_disk_use +**** Preparing the enviroment to check abort and its effect on the status variables. **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. flush status; -**** Now we are going to create transactional changes which are long enough so -**** they will be flushed to disk... +**** Transactional changes which are long enough so they will be flushed to disk... **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. **** Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); rollback; **** Non-Transactional changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. begin; insert into t2 values( 1 ); rollback; Warnings: Warning 1196 Some non-transactional changed tables couldn't be rolled back **** Mixed changes which should not be flushed to disk and so should not -**** increase binlog_cache_disk_use. -**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1. +**** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. begin; insert into t1 values( 1 ); insert into t2 values( 1 ); diff --git a/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result index 479caed8e6b..c7f2ffab47a 100644 --- a/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result +++ b/mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result @@ -7,6 +7,8 @@ start slave; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); SET GLOBAL max_binlog_cache_size = 4096; SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; @@ -129,13 +131,18 @@ source include/diff_master_slave.inc; # [ On Slave ] SET GLOBAL max_binlog_cache_size = 4096; SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; include/stop_slave.inc include/start_slave.inc CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_stmt_cache_size' bytes of storage.*"); CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); TRUNCATE t1; SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; BEGIN; Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times COMMIT; @@ -146,6 +153,8 @@ show binlog events in 'slave-bin.000001' from ; Log_name Pos Event_type Server_id End_log_pos Info SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; include/stop_slave.inc include/start_slave.inc SELECT count(*) FROM t1; diff --git a/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result index 9c1dfebebaf..f04c229a9b6 100644 --- a/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result +++ b/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result @@ -7,6 +7,8 @@ start slave; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); SET GLOBAL max_binlog_cache_size = 4096; SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; @@ -130,13 +132,18 @@ source include/diff_master_slave.inc; # [ On Slave ] SET GLOBAL max_binlog_cache_size = 4096; SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; include/stop_slave.inc include/start_slave.inc CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_stmt_cache_size' bytes of storage.*"); CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); TRUNCATE t1; SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; BEGIN; Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times COMMIT; @@ -147,6 +154,8 @@ show binlog events in 'slave-bin.000001' from ; Log_name Pos Event_type Server_id End_log_pos Info SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; include/stop_slave.inc include/start_slave.inc SELECT count(*) FROM t1; diff --git a/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result index 479caed8e6b..c7f2ffab47a 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result +++ b/mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result @@ -7,6 +7,8 @@ start slave; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); SET GLOBAL max_binlog_cache_size = 4096; SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; @@ -129,13 +131,18 @@ source include/diff_master_slave.inc; # [ On Slave ] SET GLOBAL max_binlog_cache_size = 4096; SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; include/stop_slave.inc include/start_slave.inc CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_stmt_cache_size' bytes of storage.*"); CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); TRUNCATE t1; SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; BEGIN; Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times COMMIT; @@ -146,6 +153,8 @@ show binlog events in 'slave-bin.000001' from ; Log_name Pos Event_type Server_id End_log_pos Info SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; include/stop_slave.inc include/start_slave.inc SELECT count(*) FROM t1; diff --git a/mysql-test/suite/sys_vars/inc/binlog_stmt_cache_size_basic.inc b/mysql-test/suite/sys_vars/inc/binlog_stmt_cache_size_basic.inc new file mode 100644 index 00000000000..f5df54b7acd --- /dev/null +++ b/mysql-test/suite/sys_vars/inc/binlog_stmt_cache_size_basic.inc @@ -0,0 +1,154 @@ +################ mysql-test\t\binlog_stmt_cache_size_basic.test ################ +# # +# Variable Name: binlog_stmt_cache_size # +# Scope: GLOBAL # +# Access Type: Dynamic # +# Data Type: Numeric # +# Default Value: 32768 # +# Range: 4096 - 4294967295 # +# # +# # +# Creation Date: 2010-10-12 # +# Author: Alfranio Correia # +# # +# Description: Test Cases of Dynamic System Variable "binlog_stmt_cache_size" # +# that checks behavior of this variable in the following ways # +# * Default Value # +# * Valid & Invalid values # +# * Scope & Access method # +# * Data Integrity . # +# # +# Reference: http://dev.mysql.com/doc/refman/5.5/en/ # +# server-system-variables.html#option_mysqld_binlog_stmt_cache_size # +# # +################################################################################ + +################################################################# +# START OF binlog_stmt_cache_size TESTS # +################################################################# + +######################################################################### +# Saving initial value of binlog_stmt_cache_size in a temporary variable # +######################################################################### + +SET @start_value = @@global.binlog_stmt_cache_size; +SELECT @start_value; + +--echo '#--------------------FN_DYNVARS_006_01------------------------#' +######################################################################### +# Display the DEFAULT value of binlog_stmt_cache_size # +######################################################################### + +SET @@global.binlog_stmt_cache_size = 100; +SET @@global.binlog_stmt_cache_size = DEFAULT; +SELECT @@global.binlog_stmt_cache_size; + + +--echo '#---------------------FN_DYNVARS_006_02-------------------------#' +############################################### +# Verify default value of variable # +############################################### + +SET @@global.binlog_stmt_cache_size = @start_value; +SELECT @@global.binlog_stmt_cache_size = 32768; + + +--echo '#--------------------FN_DYNVARS_006_03------------------------#' +######################################################################### +# Change the value of binlog_stmt_cache_size to a valid value # +######################################################################### + +SET @@global.binlog_stmt_cache_size = 4096; +SELECT @@global.binlog_stmt_cache_size; +SET @@global.binlog_stmt_cache_size = 4294967295; +SELECT @@global.binlog_stmt_cache_size; +SET @@global.binlog_stmt_cache_size = 10000; +SELECT @@global.binlog_stmt_cache_size; +SET @@global.binlog_stmt_cache_size = 21221204; +SELECT @@global.binlog_stmt_cache_size; +echo 'Bug: Invalid values are coming in variable on assigning valid values'; + + +--echo '#--------------------FN_DYNVARS_006_04-------------------------#' +############################################################################ +# Change the value of binlog_stmt_cache_size to invalid value # +############################################################################ + +SET @@global.binlog_stmt_cache_size = 1024; +SELECT @@global.binlog_stmt_cache_size; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.binlog_stmt_cache_size = 10000.01; +SET @@global.binlog_stmt_cache_size = -1024; +SELECT @@global.binlog_stmt_cache_size; +SET @@global.binlog_stmt_cache_size = 42949672950; +SELECT @@global.binlog_stmt_cache_size; +echo 'Bug: Errors are not coming on assigning invalid values to variable'; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.binlog_stmt_cache_size = ON; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.binlog_stmt_cache_size = 'test'; + + +--echo '#-------------------FN_DYNVARS_006_05----------------------------#' +############################################################################ +# Test if accessing session binlog_stmt_cache_size gives error # +############################################################################ + +--Error ER_GLOBAL_VARIABLE +SET @@session.binlog_stmt_cache_size = 0; + + +--echo '#----------------------FN_DYNVARS_006_06------------------------#' +############################################################################## +# Check if the value in GLOBAL Tables matches values in variable # +############################################################################## + +SELECT @@global.binlog_stmt_cache_size = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='binlog_stmt_cache_size'; + +--echo '#---------------------FN_DYNVARS_006_07----------------------#' +################################################################### +# Check if TRUE and FALSE values can be used on variable # +################################################################### + +SET @@global.binlog_stmt_cache_size = TRUE; +SELECT @@global.binlog_stmt_cache_size; +SET @@global.binlog_stmt_cache_size = FALSE; +SELECT @@global.binlog_stmt_cache_size; +echo 'Bug: Errors are not coming on assigning TRUE/FALSE to variable'; + +--echo '#---------------------FN_DYNVARS_006_08----------------------#' +############################################################################### +# Check if accessing variable without SCOPE points to same global variable # +############################################################################### + +SET @@global.binlog_stmt_cache_size = 1; +SELECT @@binlog_stmt_cache_size = @@global.binlog_stmt_cache_size; + +--echo '#---------------------FN_DYNVARS_006_09----------------------#' +########################################################################### +# Check if binlog_stmt_cache_size can be accessed with and without @@ sign# +########################################################################### + +--Error ER_GLOBAL_VARIABLE +SET binlog_stmt_cache_size = 1; +--Error ER_PARSE_ERROR +SET global.binlog_stmt_cache_size = 1; +--Error ER_UNKNOWN_TABLE +SELECT global.binlog_stmt_cache_size; +--Error ER_BAD_FIELD_ERROR +SELECT binlog_stmt_cache_size = @@session.binlog_stmt_cache_size; + + +############################## +# Restore initial value # +############################## + +SET @@global.binlog_stmt_cache_size = @start_value; +SELECT @@global.binlog_stmt_cache_size; + + +########################################################### +# END OF binlog_stmt_cache_size TESTS # +########################################################### diff --git a/mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_32.result b/mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_32.result new file mode 100644 index 00000000000..604f671d5a4 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_32.result @@ -0,0 +1,108 @@ +SET @start_value = @@global.binlog_stmt_cache_size; +SELECT @start_value; +@start_value +32768 +'#--------------------FN_DYNVARS_006_01------------------------#' +SET @@global.binlog_stmt_cache_size = 100; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '100' +SET @@global.binlog_stmt_cache_size = DEFAULT; +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +32768 +'#---------------------FN_DYNVARS_006_02-------------------------#' +SET @@global.binlog_stmt_cache_size = @start_value; +SELECT @@global.binlog_stmt_cache_size = 32768; +@@global.binlog_stmt_cache_size = 32768 +1 +'#--------------------FN_DYNVARS_006_03------------------------#' +SET @@global.binlog_stmt_cache_size = 4096; +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4096 +SET @@global.binlog_stmt_cache_size = 4294967295; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '4294967295' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4294963200 +SET @@global.binlog_stmt_cache_size = 10000; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '10000' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +8192 +SET @@global.binlog_stmt_cache_size = 21221204; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '21221204' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +21217280 +'Bug: Invalid values are coming in variable on assigning valid values' +'#--------------------FN_DYNVARS_006_04-------------------------#' +SET @@global.binlog_stmt_cache_size = 1024; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '1024' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4096 +SET @@global.binlog_stmt_cache_size = 10000.01; +ERROR 42000: Incorrect argument type to variable 'binlog_stmt_cache_size' +SET @@global.binlog_stmt_cache_size = -1024; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '-1024' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4096 +SET @@global.binlog_stmt_cache_size = 42949672950; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '42949672950' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4294963200 +'Bug: Errors are not coming on assigning invalid values to variable' +SET @@global.binlog_stmt_cache_size = ON; +ERROR 42000: Incorrect argument type to variable 'binlog_stmt_cache_size' +SET @@global.binlog_stmt_cache_size = 'test'; +ERROR 42000: Incorrect argument type to variable 'binlog_stmt_cache_size' +'#-------------------FN_DYNVARS_006_05----------------------------#' +SET @@session.binlog_stmt_cache_size = 0; +ERROR HY000: Variable 'binlog_stmt_cache_size' is a GLOBAL variable and should be set with SET GLOBAL +'#----------------------FN_DYNVARS_006_06------------------------#' +SELECT @@global.binlog_stmt_cache_size = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='binlog_stmt_cache_size'; +@@global.binlog_stmt_cache_size = VARIABLE_VALUE +1 +'#---------------------FN_DYNVARS_006_07----------------------#' +SET @@global.binlog_stmt_cache_size = TRUE; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '1' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4096 +SET @@global.binlog_stmt_cache_size = FALSE; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '0' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4096 +'Bug: Errors are not coming on assigning TRUE/FALSE to variable' +'#---------------------FN_DYNVARS_006_08----------------------#' +SET @@global.binlog_stmt_cache_size = 1; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '1' +SELECT @@binlog_stmt_cache_size = @@global.binlog_stmt_cache_size; +@@binlog_stmt_cache_size = @@global.binlog_stmt_cache_size +1 +'#---------------------FN_DYNVARS_006_09----------------------#' +SET binlog_stmt_cache_size = 1; +ERROR HY000: Variable 'binlog_stmt_cache_size' is a GLOBAL variable and should be set with SET GLOBAL +SET global.binlog_stmt_cache_size = 1; +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 'binlog_stmt_cache_size = 1' at line 1 +SELECT global.binlog_stmt_cache_size; +ERROR 42S02: Unknown table 'global' in field list +SELECT binlog_stmt_cache_size = @@session.binlog_stmt_cache_size; +ERROR 42S22: Unknown column 'binlog_stmt_cache_size' in 'field list' +SET @@global.binlog_stmt_cache_size = @start_value; +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +32768 diff --git a/mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_64.result b/mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_64.result new file mode 100644 index 00000000000..604f671d5a4 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_64.result @@ -0,0 +1,108 @@ +SET @start_value = @@global.binlog_stmt_cache_size; +SELECT @start_value; +@start_value +32768 +'#--------------------FN_DYNVARS_006_01------------------------#' +SET @@global.binlog_stmt_cache_size = 100; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '100' +SET @@global.binlog_stmt_cache_size = DEFAULT; +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +32768 +'#---------------------FN_DYNVARS_006_02-------------------------#' +SET @@global.binlog_stmt_cache_size = @start_value; +SELECT @@global.binlog_stmt_cache_size = 32768; +@@global.binlog_stmt_cache_size = 32768 +1 +'#--------------------FN_DYNVARS_006_03------------------------#' +SET @@global.binlog_stmt_cache_size = 4096; +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4096 +SET @@global.binlog_stmt_cache_size = 4294967295; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '4294967295' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4294963200 +SET @@global.binlog_stmt_cache_size = 10000; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '10000' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +8192 +SET @@global.binlog_stmt_cache_size = 21221204; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '21221204' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +21217280 +'Bug: Invalid values are coming in variable on assigning valid values' +'#--------------------FN_DYNVARS_006_04-------------------------#' +SET @@global.binlog_stmt_cache_size = 1024; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '1024' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4096 +SET @@global.binlog_stmt_cache_size = 10000.01; +ERROR 42000: Incorrect argument type to variable 'binlog_stmt_cache_size' +SET @@global.binlog_stmt_cache_size = -1024; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '-1024' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4096 +SET @@global.binlog_stmt_cache_size = 42949672950; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '42949672950' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4294963200 +'Bug: Errors are not coming on assigning invalid values to variable' +SET @@global.binlog_stmt_cache_size = ON; +ERROR 42000: Incorrect argument type to variable 'binlog_stmt_cache_size' +SET @@global.binlog_stmt_cache_size = 'test'; +ERROR 42000: Incorrect argument type to variable 'binlog_stmt_cache_size' +'#-------------------FN_DYNVARS_006_05----------------------------#' +SET @@session.binlog_stmt_cache_size = 0; +ERROR HY000: Variable 'binlog_stmt_cache_size' is a GLOBAL variable and should be set with SET GLOBAL +'#----------------------FN_DYNVARS_006_06------------------------#' +SELECT @@global.binlog_stmt_cache_size = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='binlog_stmt_cache_size'; +@@global.binlog_stmt_cache_size = VARIABLE_VALUE +1 +'#---------------------FN_DYNVARS_006_07----------------------#' +SET @@global.binlog_stmt_cache_size = TRUE; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '1' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4096 +SET @@global.binlog_stmt_cache_size = FALSE; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '0' +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +4096 +'Bug: Errors are not coming on assigning TRUE/FALSE to variable' +'#---------------------FN_DYNVARS_006_08----------------------#' +SET @@global.binlog_stmt_cache_size = 1; +Warnings: +Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '1' +SELECT @@binlog_stmt_cache_size = @@global.binlog_stmt_cache_size; +@@binlog_stmt_cache_size = @@global.binlog_stmt_cache_size +1 +'#---------------------FN_DYNVARS_006_09----------------------#' +SET binlog_stmt_cache_size = 1; +ERROR HY000: Variable 'binlog_stmt_cache_size' is a GLOBAL variable and should be set with SET GLOBAL +SET global.binlog_stmt_cache_size = 1; +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 'binlog_stmt_cache_size = 1' at line 1 +SELECT global.binlog_stmt_cache_size; +ERROR 42S02: Unknown table 'global' in field list +SELECT binlog_stmt_cache_size = @@session.binlog_stmt_cache_size; +ERROR 42S22: Unknown column 'binlog_stmt_cache_size' in 'field list' +SET @@global.binlog_stmt_cache_size = @start_value; +SELECT @@global.binlog_stmt_cache_size; +@@global.binlog_stmt_cache_size +32768 diff --git a/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result b/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result new file mode 100644 index 00000000000..f2229a0090b --- /dev/null +++ b/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result @@ -0,0 +1,152 @@ +SET @start_value = @@global.max_binlog_stmt_cache_size; +SELECT @start_value; +@start_value +18446744073709547520 +'#--------------------FN_DYNVARS_072_01------------------------#' +SET @@global.max_binlog_stmt_cache_size = 5000; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '5000' +SET @@global.max_binlog_stmt_cache_size = DEFAULT; +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +18446744073709547520 +'#---------------------FN_DYNVARS_072_02-------------------------#' +SET @@global.max_binlog_stmt_cache_size = @start_value; +SELECT @@global.max_binlog_stmt_cache_size = 4294967295; +@@global.max_binlog_stmt_cache_size = 4294967295 +0 +'#--------------------FN_DYNVARS_072_03------------------------#' +SET @@global.max_binlog_stmt_cache_size = 4096; +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4096 +SET @@global.max_binlog_stmt_cache_size = 4294967295; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '4294967295' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4294963200 +SET @@global.max_binlog_stmt_cache_size = 4294967294; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '4294967294' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4294963200 +SET @@global.max_binlog_stmt_cache_size = 4097; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '4097' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4096 +SET @@global.max_binlog_stmt_cache_size = 65535; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '65535' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +61440 +'#--------------------FN_DYNVARS_072_04-------------------------#' +SET @@global.max_binlog_stmt_cache_size = -1; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '-1' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4096 +SET @@global.max_binlog_stmt_cache_size = 100000000000; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '100000000000' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +99999997952 +SET @@global.max_binlog_stmt_cache_size = 10000.01; +ERROR 42000: Incorrect argument type to variable 'max_binlog_stmt_cache_size' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +99999997952 +SET @@global.max_binlog_stmt_cache_size = -1024; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '-1024' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4096 +SET @@global.max_binlog_stmt_cache_size = 1024; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '1024' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4096 +SET @@global.max_binlog_stmt_cache_size = 4294967296; +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4294967296 +SET @@global.max_binlog_stmt_cache_size = 4095; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '4095' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4096 +SET @@global.max_binlog_stmt_cache_size = ON; +ERROR 42000: Incorrect argument type to variable 'max_binlog_stmt_cache_size' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4096 +SET @@global.max_binlog_stmt_cache_size = 'test'; +ERROR 42000: Incorrect argument type to variable 'max_binlog_stmt_cache_size' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4096 +'#-------------------FN_DYNVARS_072_05----------------------------#' +SET @@session.max_binlog_stmt_cache_size = 4096; +ERROR HY000: Variable 'max_binlog_stmt_cache_size' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@session.max_binlog_stmt_cache_size; +ERROR HY000: Variable 'max_binlog_stmt_cache_size' is a GLOBAL variable +'#----------------------FN_DYNVARS_072_06------------------------#' +SELECT @@global.max_binlog_stmt_cache_size = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='max_binlog_stmt_cache_size'; +@@global.max_binlog_stmt_cache_size = VARIABLE_VALUE +1 +SELECT @@max_binlog_stmt_cache_size = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='max_binlog_stmt_cache_size'; +@@max_binlog_stmt_cache_size = VARIABLE_VALUE +1 +'#---------------------FN_DYNVARS_072_07----------------------#' +SET @@global.max_binlog_stmt_cache_size = TRUE; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '1' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4096 +SET @@global.max_binlog_stmt_cache_size = FALSE; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '0' +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +4096 +'#---------------------FN_DYNVARS_072_08----------------------#' +SET @@global.max_binlog_stmt_cache_size = 5000; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '5000' +SELECT @@max_binlog_stmt_cache_size = @@global.max_binlog_stmt_cache_size; +@@max_binlog_stmt_cache_size = @@global.max_binlog_stmt_cache_size +1 +'#---------------------FN_DYNVARS_072_09----------------------#' +SET max_binlog_stmt_cache_size = 6000; +ERROR HY000: Variable 'max_binlog_stmt_cache_size' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@max_binlog_stmt_cache_size; +@@max_binlog_stmt_cache_size +4096 +SET local.max_binlog_stmt_cache_size = 7000; +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 'max_binlog_stmt_cache_size = 7000' at line 1 +SELECT local.max_binlog_stmt_cache_size; +ERROR 42S02: Unknown table 'local' in field list +SET global.max_binlog_stmt_cache_size = 8000; +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 'max_binlog_stmt_cache_size = 8000' at line 1 +SELECT global.max_binlog_stmt_cache_size; +ERROR 42S02: Unknown table 'global' in field list +SELECT max_binlog_stmt_cache_size = @@session.max_binlog_stmt_cache_size; +ERROR 42S22: Unknown column 'max_binlog_stmt_cache_size' in 'field list' +SET @@global.max_binlog_stmt_cache_size = @start_value; +SELECT @@global.max_binlog_stmt_cache_size; +@@global.max_binlog_stmt_cache_size +18446744073709547520 diff --git a/mysql-test/suite/sys_vars/t/binlog_stmt_cache_size_basic_32.test b/mysql-test/suite/sys_vars/t/binlog_stmt_cache_size_basic_32.test new file mode 100644 index 00000000000..fe8f89ccc16 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/binlog_stmt_cache_size_basic_32.test @@ -0,0 +1,7 @@ +################################################################################ +# Wrapper for 32 bit machines # +################################################################################ + +--source include/have_32bit.inc +--source suite/sys_vars/inc/binlog_stmt_cache_size_basic.inc + diff --git a/mysql-test/suite/sys_vars/t/binlog_stmt_cache_size_basic_64.test b/mysql-test/suite/sys_vars/t/binlog_stmt_cache_size_basic_64.test new file mode 100644 index 00000000000..c4a2c95d42b --- /dev/null +++ b/mysql-test/suite/sys_vars/t/binlog_stmt_cache_size_basic_64.test @@ -0,0 +1,7 @@ +################################################################################ +# Wrapper for 64 bit machines # +################################################################################ + +--source include/have_64bit.inc +--source suite/sys_vars/inc/binlog_stmt_cache_size_basic.inc + diff --git a/mysql-test/suite/sys_vars/t/max_binlog_cache_size_func-master.opt b/mysql-test/suite/sys_vars/t/max_binlog_cache_size_func-master.opt deleted file mode 100644 index 6e00d7157d6..00000000000 --- a/mysql-test/suite/sys_vars/t/max_binlog_cache_size_func-master.opt +++ /dev/null @@ -1,2 +0,0 @@ ---log-bin ---innodb diff --git a/mysql-test/suite/sys_vars/t/max_binlog_stmt_cache_size_basic.test b/mysql-test/suite/sys_vars/t/max_binlog_stmt_cache_size_basic.test new file mode 100644 index 00000000000..07a030c35a7 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/max_binlog_stmt_cache_size_basic.test @@ -0,0 +1,184 @@ +############ mysql-test\t\max_binlog_stmt_cache_size_basic.test ############### +# # +# Variable Name: max_binlog_stmt_cache_size # +# Scope: GLOBAL # +# Access Type: Dynamic # +# Data Type: numeric # +# Default Value:4294967295 # +# Range: 4096-4294967295 # +# # +# # +# # +# # +# # +# Creation Date: 2010-11-05 # +# Author: Alfranio # +# # +# Description: Test Cases of Dynamic System Variable # +# max_binlog_stmt_cache_size that checks # +# the behavior of this variable in the following ways # +# * Default Value # +# * Valid & Invalid values # +# * Scope & Access method # +# * Data Integrity # +# # +# Reference: http://dev.mysql.com/doc/refman/5.5/en/ # +# server-system-variables.html # +# # +############################################################################### + +--source include/load_sysvars.inc + +########################################################################## +# START OF max_binlog_stmt_cache_size TESTS # +########################################################################## + + +############################################################################## +# Saving initial value of max_binlog_stmt_cache_size in a temporary variable # +############################################################################## + +SET @start_value = @@global.max_binlog_stmt_cache_size; +SELECT @start_value; + + +--echo '#--------------------FN_DYNVARS_072_01------------------------#' +######################################################################## +# Display the DEFAULT value of max_binlog_stmt_cache_size # +######################################################################## + +SET @@global.max_binlog_stmt_cache_size = 5000; +SET @@global.max_binlog_stmt_cache_size = DEFAULT; +SELECT @@global.max_binlog_stmt_cache_size; + + +--echo '#---------------------FN_DYNVARS_072_02-------------------------#' +############################################### +# Verify default value of variable # +############################################### + +SET @@global.max_binlog_stmt_cache_size = @start_value; +SELECT @@global.max_binlog_stmt_cache_size = 4294967295; + +--echo '#--------------------FN_DYNVARS_072_03------------------------#' +######################################################################## +# Change the value of max_binlog_stmt_cache_size to a valid value # +######################################################################## + +SET @@global.max_binlog_stmt_cache_size = 4096; +SELECT @@global.max_binlog_stmt_cache_size; +SET @@global.max_binlog_stmt_cache_size = 4294967295; +SELECT @@global.max_binlog_stmt_cache_size; +SET @@global.max_binlog_stmt_cache_size = 4294967294; +SELECT @@global.max_binlog_stmt_cache_size; +SET @@global.max_binlog_stmt_cache_size = 4097; +SELECT @@global.max_binlog_stmt_cache_size; +SET @@global.max_binlog_stmt_cache_size = 65535; +SELECT @@global.max_binlog_stmt_cache_size; + + +--echo '#--------------------FN_DYNVARS_072_04-------------------------#' +########################################################################### +# Change the value of max_binlog_stmt_cache_size to invalid value # +########################################################################### + +SET @@global.max_binlog_stmt_cache_size = -1; +SELECT @@global.max_binlog_stmt_cache_size; +SET @@global.max_binlog_stmt_cache_size = 100000000000; +SELECT @@global.max_binlog_stmt_cache_size; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.max_binlog_stmt_cache_size = 10000.01; +SELECT @@global.max_binlog_stmt_cache_size; +SET @@global.max_binlog_stmt_cache_size = -1024; +SELECT @@global.max_binlog_stmt_cache_size; +SET @@global.max_binlog_stmt_cache_size = 1024; +SELECT @@global.max_binlog_stmt_cache_size; +SET @@global.max_binlog_stmt_cache_size = 4294967296; +SELECT @@global.max_binlog_stmt_cache_size; +SET @@global.max_binlog_stmt_cache_size = 4095; +SELECT @@global.max_binlog_stmt_cache_size; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.max_binlog_stmt_cache_size = ON; +SELECT @@global.max_binlog_stmt_cache_size; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.max_binlog_stmt_cache_size = 'test'; +SELECT @@global.max_binlog_stmt_cache_size; + + +--echo '#-------------------FN_DYNVARS_072_05----------------------------#' +########################################################################### +# Test if accessing session max_binlog_stmt_cache_size gives error # +########################################################################### + +--Error ER_GLOBAL_VARIABLE +SET @@session.max_binlog_stmt_cache_size = 4096; +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.max_binlog_stmt_cache_size; + + +--echo '#----------------------FN_DYNVARS_072_06------------------------#' +############################################################################## +# Check if the value in GLOBAL & SESSION Tables matches values in variable # +############################################################################## + +SELECT @@global.max_binlog_stmt_cache_size = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='max_binlog_stmt_cache_size'; + +SELECT @@max_binlog_stmt_cache_size = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='max_binlog_stmt_cache_size'; + + +--echo '#---------------------FN_DYNVARS_072_07----------------------#' +################################################################### +# Check if TRUE and FALSE values can be used on variable # +################################################################### + +SET @@global.max_binlog_stmt_cache_size = TRUE; +SELECT @@global.max_binlog_stmt_cache_size; +SET @@global.max_binlog_stmt_cache_size = FALSE; +SELECT @@global.max_binlog_stmt_cache_size; + + +--echo '#---------------------FN_DYNVARS_072_08----------------------#' +######################################################################################################## +# Check if accessing variable with SESSION,LOCAL and without SCOPE points to same session variable # +######################################################################################################## + +SET @@global.max_binlog_stmt_cache_size = 5000; +SELECT @@max_binlog_stmt_cache_size = @@global.max_binlog_stmt_cache_size; + + +--echo '#---------------------FN_DYNVARS_072_09----------------------#' +################################################################################ +# Check if max_binlog_stmt_cache_size can be accessed with and without @@ sign # +################################################################################ + +--Error ER_GLOBAL_VARIABLE +SET max_binlog_stmt_cache_size = 6000; +SELECT @@max_binlog_stmt_cache_size; +--Error ER_PARSE_ERROR +SET local.max_binlog_stmt_cache_size = 7000; +--Error ER_UNKNOWN_TABLE +SELECT local.max_binlog_stmt_cache_size; +--Error ER_PARSE_ERROR +SET global.max_binlog_stmt_cache_size = 8000; +--Error ER_UNKNOWN_TABLE +SELECT global.max_binlog_stmt_cache_size; +--Error ER_BAD_FIELD_ERROR +SELECT max_binlog_stmt_cache_size = @@session.max_binlog_stmt_cache_size; + + +############################## +# Restore initial value # +############################## + +SET @@global.max_binlog_stmt_cache_size = @start_value; +SELECT @@global.max_binlog_stmt_cache_size; + + +######################################################################## +# END OF max_binlog_stmt_cache_size TESTS # +######################################################################## diff --git a/sql/log.cc b/sql/log.cc index f483ae74d64..53746ec02f8 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -209,11 +209,11 @@ class binlog_cache_data { public: binlog_cache_data(): m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF), - incident(FALSE), changes_to_non_trans_temp_table_flag(FALSE) - { - cache_log.end_of_file= max_binlog_cache_size; - } - + incident(FALSE), changes_to_non_trans_temp_table_flag(FALSE), + saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0), + ptr_binlog_cache_disk_use(0) + { } + ~binlog_cache_data() { DBUG_ASSERT(empty()); @@ -262,10 +262,9 @@ public: changes_to_non_trans_temp_table_flag= FALSE; incident= FALSE; before_stmt_pos= MY_OFF_T_UNDEF; - cache_log.end_of_file= max_binlog_cache_size; /* The truncate function calls reinit_io_cache that calls my_b_flush_io_cache - which may increase disk_write. This breaks the "disk_writes"' use by the + which may increase disk_writes. This breaks the disk_writes use by the binary log which aims to compute the ratio between in-memory cache usage and disk cache usage. To avoid this undesirable behavior, we reset the variable after truncating the cache. @@ -301,6 +300,36 @@ public: before_stmt_pos= MY_OFF_T_UNDEF; } + void set_binlog_cache_info(ulong param_max_binlog_cache_size, + ulong *param_ptr_binlog_cache_use, + ulong *param_ptr_binlog_cache_disk_use) + { + /* + The assertions guarantee that the set_binlog_cache_info is + called just once and information passed as parameters are + never zero. + + This is done while calling the constructor binlog_cache_mngr. + We cannot set informaton in the constructor binlog_cache_data + because the space for binlog_cache_mngr is allocated through + a placement new. + + In the future, we can refactor this and change it to avoid + the set_binlog_info. + */ + DBUG_ASSERT(saved_max_binlog_cache_size == 0 && + param_max_binlog_cache_size != 0 && + ptr_binlog_cache_use == 0 && + param_ptr_binlog_cache_use != 0 && + ptr_binlog_cache_disk_use == 0 && + param_ptr_binlog_cache_disk_use != 0); + + saved_max_binlog_cache_size= param_max_binlog_cache_size; + ptr_binlog_cache_use= param_ptr_binlog_cache_use; + ptr_binlog_cache_disk_use= param_ptr_binlog_cache_disk_use; + cache_log.end_of_file= saved_max_binlog_cache_size; + } + /* Cache to store data before copying it to the binary log. */ @@ -332,20 +361,38 @@ private: /** This function computes binlog cache and disk usage. - - @param cache_data Pointer to the cache where data is - stored. */ void compute_statistics() { if (!empty()) { - statistic_increment(binlog_cache_use, &LOCK_status); + statistic_increment(*ptr_binlog_cache_use, &LOCK_status); if (cache_log.disk_writes != 0) - statistic_increment(binlog_cache_disk_use, &LOCK_status); + statistic_increment(*ptr_binlog_cache_disk_use, &LOCK_status); } } + /* + Stores the values of maximum size of the cache allowed when this cache + is configured. This corresponds to either + . max_binlog_cache_size or max_binlog_stmt_cache_size. + */ + ulong saved_max_binlog_cache_size; + + /* + Stores a pointer to the status variable that keeps track of the in-memory + cache usage. This corresponds to either + . binlog_cache_use or binlog_stmt_cache_use. + */ + ulong *ptr_binlog_cache_use; + + /* + Stores a pointer to the status variable that keeps track of the disk + cache usage. This corresponds to either + . binlog_cache_disk_use or binlog_stmt_cache_disk_use. + */ + ulong *ptr_binlog_cache_disk_use; + /* It truncates the cache to a certain position. This includes deleting the pending event. @@ -359,7 +406,7 @@ private: set_pending(0); } reinit_io_cache(&cache_log, WRITE_CACHE, pos, 0, 0); - cache_log.end_of_file= max_binlog_cache_size; + cache_log.end_of_file= saved_max_binlog_cache_size; } binlog_cache_data& operator=(const binlog_cache_data& info); @@ -368,7 +415,20 @@ private: class binlog_cache_mngr { public: - binlog_cache_mngr() {} + binlog_cache_mngr(ulong param_max_binlog_stmt_cache_size, + ulong param_max_binlog_cache_size, + ulong *param_ptr_binlog_stmt_cache_use, + ulong *param_ptr_binlog_stmt_cache_disk_use, + ulong *param_ptr_binlog_cache_use, + ulong *param_ptr_binlog_cache_disk_use) + { + stmt_cache.set_binlog_cache_info(param_max_binlog_stmt_cache_size, + param_ptr_binlog_stmt_cache_use, + param_ptr_binlog_stmt_cache_disk_use); + trx_cache.set_binlog_cache_info(param_max_binlog_cache_size, + param_ptr_binlog_cache_use, + param_ptr_binlog_cache_disk_use); + } void reset_cache(binlog_cache_data* cache_data) { @@ -1877,7 +1937,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) DBUG_RETURN(error); } -void MYSQL_BIN_LOG::set_write_error(THD *thd) +void MYSQL_BIN_LOG::set_write_error(THD *thd, bool is_transactional) { DBUG_ENTER("MYSQL_BIN_LOG::set_write_error"); @@ -1887,9 +1947,20 @@ void MYSQL_BIN_LOG::set_write_error(THD *thd) DBUG_VOID_RETURN; if (my_errno == EFBIG) - my_message(ER_TRANS_CACHE_FULL, ER(ER_TRANS_CACHE_FULL), MYF(MY_WME)); + { + if (is_transactional) + { + my_message(ER_TRANS_CACHE_FULL, ER(ER_TRANS_CACHE_FULL), MYF(MY_WME)); + } + else + { + my_message(ER_STMT_CACHE_FULL, ER(ER_STMT_CACHE_FULL), MYF(MY_WME)); + } + } else + { my_error(ER_ERROR_ON_WRITE, MYF(MY_WME), name, errno); + } DBUG_VOID_RETURN; } @@ -1906,6 +1977,7 @@ bool MYSQL_BIN_LOG::check_write_error(THD *thd) switch (thd->stmt_da->sql_errno()) { case ER_TRANS_CACHE_FULL: + case ER_STMT_CACHE_FULL: case ER_ERROR_ON_WRITE: case ER_BINLOG_LOGGING_IMPOSSIBLE: checked= TRUE; @@ -4398,7 +4470,7 @@ int THD::binlog_setup_trx_data() cache_mngr= (binlog_cache_mngr*) my_malloc(sizeof(binlog_cache_mngr), MYF(MY_ZEROFILL)); if (!cache_mngr || open_cached_file(&cache_mngr->stmt_cache.cache_log, mysql_tmpdir, - LOG_PREFIX, binlog_cache_size, MYF(MY_WME)) || + LOG_PREFIX, binlog_stmt_cache_size, MYF(MY_WME)) || open_cached_file(&cache_mngr->trx_cache.cache_log, mysql_tmpdir, LOG_PREFIX, binlog_cache_size, MYF(MY_WME))) { @@ -4407,8 +4479,13 @@ int THD::binlog_setup_trx_data() } thd_set_ha_data(this, binlog_hton, cache_mngr); - cache_mngr= new (thd_get_ha_data(this, binlog_hton)) binlog_cache_mngr; - + cache_mngr= new (thd_get_ha_data(this, binlog_hton)) + binlog_cache_mngr(max_binlog_stmt_cache_size, + max_binlog_cache_size, + &binlog_stmt_cache_use, + &binlog_stmt_cache_disk_use, + &binlog_cache_use, + &binlog_cache_disk_use); DBUG_RETURN(0); } @@ -4660,7 +4737,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd, */ if (pending->write(file)) { - set_write_error(thd); + set_write_error(thd, is_transactional); if (check_write_error(thd) && cache_data && stmt_has_updated_non_trans_table(thd)) cache_data->set_incident(); @@ -4685,6 +4762,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) bool error= 1; DBUG_ENTER("MYSQL_BIN_LOG::write(Log_event *)"); binlog_cache_data *cache_data= 0; + bool is_trans_cache= FALSE; if (thd->binlog_evt_union.do_union) { @@ -4745,7 +4823,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) binlog_cache_mngr *const cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); - bool is_trans_cache= use_trans_cache(thd, event_info->use_trans_cache()); + is_trans_cache= use_trans_cache(thd, event_info->use_trans_cache()); file= cache_mngr->get_binlog_cache_log(is_trans_cache); cache_data= cache_mngr->get_binlog_cache_data(is_trans_cache); @@ -4851,7 +4929,7 @@ unlock: if (error) { - set_write_error(thd); + set_write_error(thd, is_trans_cache); if (check_write_error(thd) && cache_data && stmt_has_updated_non_trans_table(thd)) cache_data->set_incident(); diff --git a/sql/log.h b/sql/log.h index 89b3594cd1e..df7ed61a473 100644 --- a/sql/log.h +++ b/sql/log.h @@ -399,7 +399,7 @@ public: bool write_incident(THD *thd, bool lock); int write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync); - void set_write_error(THD *thd); + void set_write_error(THD *thd, bool is_transactional); bool check_write_error(THD *thd); void start_union_events(THD *thd, query_id_t query_id_param); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index df4f0f95b8c..86013dace31 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -460,6 +460,8 @@ ulonglong slave_type_conversions_options; ulong thread_cache_size=0; ulong binlog_cache_size=0; ulonglong max_binlog_cache_size=0; +ulong binlog_stmt_cache_size=0; +ulonglong max_binlog_stmt_cache_size=0; ulong query_cache_size=0; ulong refresh_version; /* Increments on each reload */ query_id_t global_query_id; @@ -471,6 +473,7 @@ ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use; ulong delayed_insert_errors,flush_time; ulong specialflag=0; ulong binlog_cache_use= 0, binlog_cache_disk_use= 0; +ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0; ulong max_connections, max_connect_errors; /** Limit of the total number of prepared statements in the server. @@ -6406,6 +6409,8 @@ SHOW_VAR status_vars[]= { {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG}, {"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG}, + {"Binlog_stmt_cache_disk_use",(char*) &binlog_stmt_cache_disk_use, SHOW_LONG}, + {"Binlog_stmt_cache_use", (char*) &binlog_stmt_cache_use, SHOW_LONG}, {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS}, {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS}, {"Com", (char*) com_status_vars, SHOW_ARRAY}, diff --git a/sql/mysqld.h b/sql/mysqld.h index 6e81c240f7d..4988248e936 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -152,6 +152,7 @@ extern ulonglong keybuff_size; extern ulonglong thd_startup_options; extern ulong thread_id; extern ulong binlog_cache_use, binlog_cache_disk_use; +extern ulong binlog_stmt_cache_use, binlog_stmt_cache_disk_use; extern ulong aborted_threads,aborted_connects; extern ulong delayed_insert_timeout; extern ulong delayed_insert_limit, delayed_queue_size; @@ -171,8 +172,9 @@ extern uint slave_net_timeout; extern uint max_user_connections; extern ulong what_to_log,flush_time; extern ulong max_prepared_stmt_count, prepared_stmt_count; -extern ulong binlog_cache_size, open_files_limit; -extern ulonglong max_binlog_cache_size; +extern ulong open_files_limit; +extern ulong binlog_cache_size, binlog_stmt_cache_size; +extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size; extern ulong max_binlog_size, max_relay_log_size; extern ulong opt_binlog_rows_event_max_size; extern ulong rpl_recovery_rank, thread_cache_size; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index be97afe055a..b0dc4d9195b 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6392,3 +6392,5 @@ ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX eng "The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout." +ER_STMT_CACHE_FULL + eng "Multi-row statements required more than 'max_binlog_stmt_cache_size' bytes of storage; increase this mysqld variable and try again" diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 5c9df82ddac..ed2c44fb03f 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -236,14 +236,23 @@ static Sys_var_charptr Sys_basedir( IN_FS_CHARSET, DEFAULT(0)); static Sys_var_ulong Sys_binlog_cache_size( - "binlog_cache_size", "The size of the cache to " - "hold the SQL statements for the binary log during a " - "transaction. If you often use big, multi-statement " - "transactions you can increase this to get more performance", + "binlog_cache_size", "The size of the transactional cache for " + "updates to transactional engines for the binary log. " + "If you often use transactions containing many statements, " + "you can increase this to get more performance", GLOBAL_VAR(binlog_cache_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(IO_SIZE, ULONG_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE)); +static Sys_var_ulong Sys_binlog_stmt_cache_size( + "binlog_stmt_cache_size", "The size of the statement cache for " + "updates to non-transactional engines for the binary log. " + "If you often use statements updating a great number of rows, " + "you can increase this to get more performance", + GLOBAL_VAR(binlog_stmt_cache_size), + CMD_LINE(REQUIRED_ARG), + VALID_RANGE(IO_SIZE, ULONG_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE)); + static bool check_has_super(sys_var *self, THD *thd, set_var *var) { DBUG_ASSERT(self->scope() != sys_var::GLOBAL);// don't abuse check_has_super() @@ -1031,13 +1040,20 @@ static Sys_var_ulong Sys_max_allowed_packet( static Sys_var_ulonglong Sys_max_binlog_cache_size( "max_binlog_cache_size", - "Can be used to restrict the total size used to cache a " - "multi-transaction query", + "Sets the total size of the transactional cache", GLOBAL_VAR(max_binlog_cache_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(IO_SIZE, ULONGLONG_MAX), DEFAULT((ULONGLONG_MAX/IO_SIZE)*IO_SIZE), BLOCK_SIZE(IO_SIZE)); +static Sys_var_ulonglong Sys_max_binlog_stmt_cache_size( + "max_binlog_stmt_cache_size", + "Sets the total size of the statement cache", + GLOBAL_VAR(max_binlog_stmt_cache_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(IO_SIZE, ULONGLONG_MAX), + DEFAULT((ULONGLONG_MAX/IO_SIZE)*IO_SIZE), + BLOCK_SIZE(IO_SIZE)); + static bool fix_max_binlog_size(sys_var *self, THD *thd, enum_var_type type) { mysql_bin_log.set_max_size(max_binlog_size); From b56f1d8283333d2cf43bbce30fd2af78d4eaf51c Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Thu, 11 Nov 2010 07:34:14 +0000 Subject: [PATCH 008/110] Bug #49752: 2469.126.2 unintentionally breaks authentication against MySQL 5.1 server Server used to clip overly long user-names. This was presumably lost when code was made UTF8-clean. Now we emulate the behaviour for backward compatibility, but UTF8-ly correct. --- mysql-test/r/connect.result | 11 +++++++++++ mysql-test/t/connect.test | 28 ++++++++++++++++++++++++++++ sql/sql_connect.cc | 13 +++++++++++++ strings/CHARSET_INFO.txt | 11 ++++------- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index 5e6c013bb38..381ae8b2562 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -215,6 +215,17 @@ SET GLOBAL event_scheduler = OFF; # -- End of Bug#35074. +# +# -- Bug#49752: 2469.126.2 unintentionally breaks authentication +# against MySQL 5.1 server +# +GRANT ALL ON test.* TO 'Azundris12345678'@'localhost' IDENTIFIED BY 'test123'; +FLUSH PRIVILEGES; +DROP USER 'Azundris12345678'@'localhost'; +FLUSH PRIVILEGES; +# +# -- End of Bug#49752 +# # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index 9a29e4ff861..d0b79ab6bd3 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -293,6 +293,34 @@ SET GLOBAL event_scheduler = OFF; --echo # -- End of Bug#35074. --echo + +########################################################################### + +--echo # +--echo # -- Bug#49752: 2469.126.2 unintentionally breaks authentication +--echo # against MySQL 5.1 server +--echo # + +GRANT ALL ON test.* TO 'Azundris12345678'@'localhost' IDENTIFIED BY 'test123'; + +FLUSH PRIVILEGES; + +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +connect (con1,localhost,Azundris123456789,test123,test); +disconnect con1; + +connection default; + +DROP USER 'Azundris12345678'@'localhost'; + +FLUSH PRIVILEGES; + +--echo # +--echo # -- End of Bug#49752 +--echo # + + + --echo # ------------------------------------------------------------------ --echo # -- End of 5.1 tests --echo # ------------------------------------------------------------------ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 28c1acc4716..9fa6966baa2 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -899,6 +899,19 @@ static int check_connection(THD *thd) user_len-= 2; } + /* + Clip username to allowed length in characters (not bytes). This is + mostly for backward compatibility. + */ + { + CHARSET_INFO *cs= system_charset_info; + int err; + + user_len= (uint) cs->cset->well_formed_len(cs, user, user + user_len, + USERNAME_CHAR_LENGTH, &err); + user[user_len]= '\0'; + } + if (thd->main_security_ctx.user) x_free(thd->main_security_ctx.user); if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME)))) diff --git a/strings/CHARSET_INFO.txt b/strings/CHARSET_INFO.txt index bb8e40025c7..6f0a810be37 100644 --- a/strings/CHARSET_INFO.txt +++ b/strings/CHARSET_INFO.txt @@ -208,14 +208,11 @@ charpos() - calculates the offset of the given position in the string. Used in SQL functions LEFT(), RIGHT(), SUBSTRING(), INSERT() -well_formed_length() - - finds the length of correctly formed multi-byte beginning. - Used in INSERTs to cut a beginning of the given string - which is - a) "well formed" according to the given character set. +well_formed_len() + - returns length of a given multi-byte string in bytes + Used in INSERTs to shorten the given string so it + a) is "well formed" according to the given character set b) can fit into the given data type - Terminates the string in the good position, taking in account - multi-byte character boundaries. lengthsp() - returns the length of the given string without trailing spaces. From 58f5b9c0ccf66b570c0462b7d9c7b37f5414b8ef Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Thu, 11 Nov 2010 11:35:48 +0000 Subject: [PATCH 009/110] Bug#43233: Some server variables are clipped during "update," not "check" stage Bug#55794: ulonglong options of mysqld show wrong values. Port the few remaining system variables to the correct mechanism -- range-check in check-stage (and throw error or warning at that point as needed and depending on STRICTness), update in update stage. Fix some signedness errors when retrieving sysvar values for display. --- mysql-test/r/variables.result | 34 ++++++++++++++++++++ mysql-test/t/variables.test | 41 ++++++++++++++++++++++++ sql/item_func.cc | 4 +-- sql/set_var.cc | 59 ++++++++++++++++++++++++----------- sql/set_var.h | 4 +++ 5 files changed, 122 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index a297dbfa502..58f88b78bda 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1511,4 +1511,38 @@ SELECT @@skip_name_resolve; SHOW VARIABLES LIKE 'skip_name_resolve'; Variable_name Value skip_name_resolve OFF +# +# Bug #43233 : Some server variables are clipped during "update," +# not "check" stage +# +SET @kbs=@@global.key_buffer_size; +SET @kcbs=@@global.key_cache_block_size; +throw errors in STRICT mode +SET SQL_MODE=STRICT_ALL_TABLES; +SET @@global.max_binlog_cache_size=-1; +ERROR 42000: Variable 'max_binlog_cache_size' can't be set to the value of '-1' +SET @@global.max_join_size=0; +ERROR 42000: Variable 'max_join_size' can't be set to the value of '0' +SET @@global.key_buffer_size=0; +ERROR 42000: Variable 'key_buffer_size' can't be set to the value of '0' +SET @@global.key_cache_block_size=0; +ERROR 42000: Variable 'key_cache_block_size' can't be set to the value of '0' +throw warnings in default mode +SET SQL_MODE=DEFAULT; +SET @@global.max_binlog_cache_size=-1; +Warnings: +Warning 1292 Truncated incorrect max_binlog_cache_size value: '-1' +SET @@global.max_join_size=0; +Warnings: +Warning 1292 Truncated incorrect max_join_size value: '0' +SET @@global.key_buffer_size=0; +Warnings: +Warning 1292 Truncated incorrect key_buffer_size value: '0' +SET @@global.key_cache_block_size=0; +Warnings: +Warning 1292 Truncated incorrect key_cache_block_size value: '0' +SET @@global.max_binlog_cache_size=DEFAULT; +SET @@global.max_join_size=DEFAULT; +SET @@global.key_buffer_size=@kbs; +SET @@global.key_cache_block_size=@kcbs; End of 5.1 tests diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index d5929041e8a..1b411d9420c 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -1255,4 +1255,45 @@ SET GLOBAL max_binlog_cache_size = @old_max_binlog_cache_size; SELECT @@skip_name_resolve; SHOW VARIABLES LIKE 'skip_name_resolve'; +--echo # +--echo # Bug #43233 : Some server variables are clipped during "update," +--echo # not "check" stage +--echo # + +SET @kbs=@@global.key_buffer_size; +SET @kcbs=@@global.key_cache_block_size; + +--echo throw errors in STRICT mode +SET SQL_MODE=STRICT_ALL_TABLES; + +# sys_var_ulonglong_ptr: sys_max_binlog_cache_size +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.max_binlog_cache_size=-1; + +# sys_var_thd_ha_rows: "max_join_size" et al. +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.max_join_size=0; + +# sys_var_key_buffer_size: "key_buffer_size" +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.key_buffer_size=0; + +# sys_var_key_cache_long: "key_cache_block_size" et al. +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.key_cache_block_size=0; + +--echo throw warnings in default mode +SET SQL_MODE=DEFAULT; + +SET @@global.max_binlog_cache_size=-1; +SET @@global.max_join_size=0; +SET @@global.key_buffer_size=0; +SET @@global.key_cache_block_size=0; + +# cleanup +SET @@global.max_binlog_cache_size=DEFAULT; +SET @@global.max_join_size=DEFAULT; +SET @@global.key_buffer_size=@kbs; +SET @@global.key_cache_block_size=@kcbs; + --echo End of 5.1 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index 1b13297c951..cb19afc4fd5 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4843,7 +4843,7 @@ void Item_func_get_system_var::fix_length_and_dec() decimals=0; break; case SHOW_LONGLONG: - unsigned_flag= FALSE; + unsigned_flag= TRUE; max_length= MY_INT64_NUM_DECIMAL_DIGITS; decimals=0; break; @@ -4984,7 +4984,7 @@ longlong Item_func_get_system_var::val_int() { case SHOW_INT: get_sys_var_safe (uint); case SHOW_LONG: get_sys_var_safe (ulong); - case SHOW_LONGLONG: get_sys_var_safe (longlong); + case SHOW_LONGLONG: get_sys_var_safe (ulonglong); case SHOW_HA_ROWS: get_sys_var_safe (ha_rows); case SHOW_BOOL: get_sys_var_safe (bool); case SHOW_MY_BOOL: get_sys_var_safe (my_bool); diff --git a/sql/set_var.cc b/sql/set_var.cc index c5517da92f8..50659651dc0 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1579,11 +1579,16 @@ void sys_var_long_ptr_global::set_default(THD *thd, enum_var_type type) } +bool sys_var_ulonglong_ptr::check(THD *thd, set_var *var) +{ + return get_unsigned(thd, var, 0, GET_ULL); +} + + bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var) { ulonglong tmp= var->save_result.ulonglong_value; pthread_mutex_lock(&LOCK_global_system_variables); - bound_unsigned(thd, &tmp, option_limits); *value= (ulonglong) tmp; pthread_mutex_unlock(&LOCK_global_system_variables); return 0; @@ -1675,25 +1680,30 @@ uchar *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type, } +bool sys_var_thd_ha_rows::check(THD *thd, set_var *var) +{ + return get_unsigned(thd, var, max_system_variables.*offset, +#ifdef BIG_TABLES + GET_ULL +#else + GET_ULONG +#endif + ); +} + + bool sys_var_thd_ha_rows::update(THD *thd, set_var *var) { - ulonglong tmp= var->save_result.ulonglong_value; - - /* Don't use bigger value than given with --maximum-variable-name=.. */ - if ((ha_rows) tmp > max_system_variables.*offset) - tmp= max_system_variables.*offset; - - bound_unsigned(thd, &tmp, option_limits); - if (var->type == OPT_GLOBAL) { /* Lock is needed to make things safe on 32 bit systems */ - pthread_mutex_lock(&LOCK_global_system_variables); - global_system_variables.*offset= (ha_rows) tmp; + pthread_mutex_lock(&LOCK_global_system_variables); + global_system_variables.*offset= (ha_rows) + var->save_result.ulonglong_value; pthread_mutex_unlock(&LOCK_global_system_variables); } else - thd->variables.*offset= (ha_rows) tmp; + thd->variables.*offset= (ha_rows) var->save_result.ulonglong_value; return 0; } @@ -2305,6 +2315,12 @@ uchar *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type, } +bool sys_var_key_buffer_size::check(THD *thd, set_var *var) +{ + return get_unsigned(thd, var, 0, GET_ULL); +} + + bool sys_var_key_buffer_size::update(THD *thd, set_var *var) { ulonglong tmp= var->save_result.ulonglong_value; @@ -2318,10 +2334,10 @@ bool sys_var_key_buffer_size::update(THD *thd, set_var *var) pthread_mutex_lock(&LOCK_global_system_variables); key_cache= get_key_cache(base_name); - + if (!key_cache) { - /* Key cache didn't exists */ + /* Key cache didn't exist */ if (!tmp) // Tried to delete cache goto end; // Ok, nothing to do if (!(key_cache= create_key_cache(base_name->str, base_name->length))) @@ -2371,7 +2387,6 @@ bool sys_var_key_buffer_size::update(THD *thd, set_var *var) goto end; } - bound_unsigned(thd, &tmp, option_limits); key_cache->param_buff_size= (ulonglong) tmp; /* If key cache didn't exist initialize it, else resize it */ @@ -2388,10 +2403,19 @@ bool sys_var_key_buffer_size::update(THD *thd, set_var *var) end: pthread_mutex_unlock(&LOCK_global_system_variables); + + var->save_result.ulonglong_value = SIZE_T_MAX; + return error; } +bool sys_var_key_cache_long::check(THD *thd, set_var *var) +{ + return get_unsigned(thd, var, 0, GET_ULONG); +} + + /** @todo Abort if some other thread is changing the key cache. @@ -2400,7 +2424,6 @@ end: */ bool sys_var_key_cache_long::update(THD *thd, set_var *var) { - ulonglong tmp= var->value->val_int(); LEX_STRING *base_name= &var->base; bool error= 0; @@ -2425,8 +2448,8 @@ bool sys_var_key_cache_long::update(THD *thd, set_var *var) if (key_cache->in_init) goto end; - bound_unsigned(thd, &tmp, option_limits); - *((ulong*) (((char*) key_cache) + offset))= (ulong) tmp; + *((ulong*) (((char*) key_cache) + offset))= (ulong) + var->save_result.ulonglong_value; /* Don't create a new key cache if it didn't exist diff --git a/sql/set_var.h b/sql/set_var.h index 68cd94a5670..f2d2e5d2693 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -196,6 +196,7 @@ public: sys_after_update_func func) :sys_var(name_arg,func), value(value_ptr_arg) { chain_sys_var(chain); } + bool check(THD *thd, set_var *var); bool update(THD *thd, set_var *var); void set_default(THD *thd, enum_var_type type); SHOW_TYPE show_type() { return SHOW_LONGLONG; } @@ -442,6 +443,7 @@ public: sys_after_update_func func) :sys_var_thd(name_arg,func), offset(offset_arg) { chain_sys_var(chain); } + bool check(THD *thd, set_var *var); bool update(THD *thd, set_var *var); void set_default(THD *thd, enum_var_type type); SHOW_TYPE show_type() { return SHOW_HA_ROWS; } @@ -854,6 +856,7 @@ public: :sys_var_key_cache_param(chain, name_arg, offsetof(KEY_CACHE, param_buff_size)) {} + bool check(THD *thd, set_var *var); bool update(THD *thd, set_var *var); SHOW_TYPE show_type() { return SHOW_LONGLONG; } }; @@ -865,6 +868,7 @@ public: sys_var_key_cache_long(sys_var_chain *chain, const char *name_arg, size_t offset_arg) :sys_var_key_cache_param(chain, name_arg, offset_arg) {} + bool check(THD *thd, set_var *var); bool update(THD *thd, set_var *var); SHOW_TYPE show_type() { return SHOW_LONG; } }; From fb140a87d3e32de982e1a1d5c6816dda34954cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Bl=C3=A5udd?= Date: Tue, 16 Nov 2010 10:05:54 +0100 Subject: [PATCH 010/110] Bug#58158 LINK_LIBRARIES for MYSQL_ADD_PLUGIN is not added to libmysqld - Add ARG_LINK_LIBRARIES to MYSQLD_STATIC_PLUGIN_LIBS in MYSQL_ADD_PLUGIN so that any libraries listed by the plugin is added to libmysqld - remove the variables NDB_CLIENT_LIBS and NDB_CLUSTER_INCLUDES from libmysqld/CMakeLists.txt since those are just old remnants --- cmake/plugin.cmake | 2 +- libmysqld/CMakeLists.txt | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index 94fdc8bf1e9..6ff7e794440 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -123,7 +123,7 @@ MACRO(MYSQL_ADD_PLUGIN) # Update mysqld dependencies SET (MYSQLD_STATIC_PLUGIN_LIBS ${MYSQLD_STATIC_PLUGIN_LIBS} - ${target} CACHE INTERNAL "" FORCE) + ${target} ${ARG_LINK_LIBRARIES} CACHE INTERNAL "" FORCE) IF(ARG_MANDATORY) SET(${with_var} ON CACHE INTERNAL "Link ${plugin} statically to the server" diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index 545d03532c1..25f4b752a30 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -26,7 +26,6 @@ ${CMAKE_SOURCE_DIR}/regex ${ZLIB_INCLUDE_DIR} ${SSL_INCLUDE_DIRS} ${SSL_INTERNAL_INCLUDE_DIRS} -${NDB_CLUSTER_INCLUDES} ${CMAKE_SOURCE_DIR}/sql/backup ) @@ -110,7 +109,7 @@ SET(LIBS dbug strings regex mysys vio ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBWRAP} ${LIBCRYPT} ${LIBDL} - ${MYSQLD_STATIC_PLUGIN_LIBS} ${NDB_CLIENT_LIBS} + ${MYSQLD_STATIC_PLUGIN_LIBS} sql_embedded ) From f9c3be71d1f8bf543f135719f6c15d095b574e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Bl=C3=A5udd?= Date: Wed, 24 Nov 2010 11:37:59 +0100 Subject: [PATCH 011/110] WL#5665: Removal of the autotools-based build system - Make the cmake files depend on VERSION, causing cmake rerun when VERSION changes --- cmake/mysql_version.cmake | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake index b4be85ff657..3ed93020e8a 100644 --- a/cmake/mysql_version.cmake +++ b/cmake/mysql_version.cmake @@ -21,17 +21,21 @@ SET(SHARED_LIB_MAJOR_VERSION "16") SET(PROTOCOL_VERSION "10") SET(DOT_FRM_VERSION "6") +# Generate "something" to trigger cmake rerun when VERSION changes +CONFIGURE_FILE( + ${CMAKE_SOURCE_DIR}/VERSION + ${CMAKE_BINARY_DIR}/VERSION.dep +) + # Read value for a variable from VERSION. MACRO(MYSQL_GET_CONFIG_VALUE keyword var) IF(NOT ${var}) - IF (EXISTS ${CMAKE_SOURCE_DIR}/VERSION) - FILE (STRINGS ${CMAKE_SOURCE_DIR}/VERSION str REGEX "^[ ]*${keyword}=") - IF(str) - STRING(REPLACE "${keyword}=" "" str ${str}) - STRING(REGEX REPLACE "[ ].*" "" str "${str}") - SET(${var} ${str}) - ENDIF() + FILE (STRINGS ${CMAKE_SOURCE_DIR}/VERSION str REGEX "^[ ]*${keyword}=") + IF(str) + STRING(REPLACE "${keyword}=" "" str ${str}) + STRING(REGEX REPLACE "[ ].*" "" str "${str}") + SET(${var} ${str}) ENDIF() ENDIF() ENDMACRO() From 229da09502bdff7621001e3cdb6556a4b5025e66 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Tue, 23 Nov 2010 10:26:26 +0100 Subject: [PATCH 012/110] Bug #58372 cmake should not write temporary files in the source directory --- cmake/do_abi_check.cmake | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/cmake/do_abi_check.cmake b/cmake/do_abi_check.cmake index 78006bd018c..96943e1a4c4 100644 --- a/cmake/do_abi_check.cmake +++ b/cmake/do_abi_check.cmake @@ -53,23 +53,27 @@ SET(abi_check_out ${BINARY_DIR}/abi_check.out) FOREACH(file ${ABI_HEADERS}) - SET(tmpfile ${file}.pp.tmp) - EXECUTE_PROCESS( - COMMAND ${COMPILER} - -E -nostdinc -dI -DMYSQL_ABI_CHECK -I${SOURCE_DIR}/include - -I${BINARY_DIR}/include -I${SOURCE_DIR}/include/mysql -I${SOURCE_DIR}/sql - ${file} - ERROR_QUIET OUTPUT_FILE ${tmpfile}) - EXECUTE_PROCESS( - COMMAND sed -e - "/^# /d" -e "/^[ ]*$/d" -e "/^#pragma GCC set_debug_pwd/d" -e "/^#ident/d" - RESULT_VARIABLE result OUTPUT_FILE ${abi_check_out} INPUT_FILE ${tmpfile}) + GET_FILENAME_COMPONENT(header_basename ${file} NAME) + SET(tmpfile ${BINARY_DIR}/${header_basename}.pp.tmp) + + EXECUTE_PROCESS( + COMMAND ${COMPILER} + -E -nostdinc -dI -DMYSQL_ABI_CHECK -I${SOURCE_DIR}/include + -I${BINARY_DIR}/include -I${SOURCE_DIR}/include/mysql -I${SOURCE_DIR}/sql + ${file} + ERROR_QUIET OUTPUT_FILE ${tmpfile}) + EXECUTE_PROCESS( + COMMAND sed -e "/^# /d" + -e "/^[ ]*$/d" + -e "/^#pragma GCC set_debug_pwd/d" + -e "/^#ident/d" + RESULT_VARIABLE result OUTPUT_FILE ${abi_check_out} INPUT_FILE ${tmpfile}) IF(NOT ${result} EQUAL 0) MESSAGE(FATAL_ERROR "sed returned error ${result}") ENDIF() FILE(REMOVE ${tmpfile}) - EXECUTE_PROCESS(COMMAND diff -w ${file}.pp ${abi_check_out} RESULT_VARIABLE - result) + EXECUTE_PROCESS( + COMMAND diff -w ${file}.pp ${abi_check_out} RESULT_VARIABLE result) IF(NOT ${result} EQUAL 0) MESSAGE(FATAL_ERROR "ABI check found difference between ${file}.pp and ${abi_check_out}") From f2b4622346086f3cf46d81c2bca0f8c0a1948715 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 23 Nov 2010 14:34:00 +0100 Subject: [PATCH 013/110] Bug #43418 MTR2: does not notice a memory leak occuring at shutdown of mysqld w/ --valgrind Follow-up discussed with Reporter: Avoid hard shutdown after test failure, if caused by server log warning AND we are running valgrind More general pick-up of valgrind summaries, order may apparently vary Do exit(1) if we did find valgrind summary warnings --- mysql-test/mysql-test-run.pl | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index b4cd53cff09..ae82bf5a589 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -568,7 +568,10 @@ sub run_test_server ($$$) { if ( !$opt_force ) { # Test has failed, force is off push(@$completed, $result); - return $completed; + return $completed unless $result->{'dont_kill_server'}; + # Prevent kill of server, to get valgrind report + print $sock "BYE\n"; + next; } elsif ($opt_max_test_fail > 0 and $num_failed_test >= $opt_max_test_fail) { @@ -808,13 +811,14 @@ sub run_worker ($) { elsif ($line eq 'BYE'){ mtr_report("Server said BYE"); stop_all_servers($opt_shutdown_timeout); + my $valgrind_reports= 0; if ($opt_valgrind_mysqld) { - valgrind_exit_reports(); + $valgrind_reports= valgrind_exit_reports(); } if ( $opt_gprof ) { gprof_collect (find_mysqld($basedir), keys %gprof_dirs); } - exit(0); + exit($valgrind_reports); } else { mtr_error("Could not understand server, '$line'"); @@ -4232,7 +4236,12 @@ sub after_failure ($) { sub report_failure_and_restart ($) { my $tinfo= shift; - stop_all_servers(); + if ($opt_valgrind_mysqld && ($tinfo->{'warnings'} || $tinfo->{'timeout'})) { + # In these cases we may want valgrind report from normal termination + $tinfo->{'dont_kill_server'}= 1; + } + # Shotdown properly if not to be killed (for valgrind) + stop_all_servers($tinfo->{'dont_kill_server'} ? $opt_shutdown_timeout : 0); $tinfo->{'result'}= 'MTR_RES_FAILED'; @@ -5359,6 +5368,8 @@ sub valgrind_arguments { # sub valgrind_exit_reports() { + my $found_err= 0; + foreach my $log_file (keys %mysqld_logs) { my @culprits= (); @@ -5394,7 +5405,7 @@ sub valgrind_exit_reports() { next; } # This line marks the start of a valgrind report - $found_report= 1 if $line =~ /ERROR SUMMARY:/; + $found_report= 1 if $line =~ /^==\d+== .* SUMMARY:/; if ($found_report) { $line=~ s/^==\d+== //; @@ -5411,8 +5422,11 @@ sub valgrind_exit_reports() { mtr_print ("Valgrind report from $log_file after tests:\n", @culprits); mtr_print_line(); print ("$valgrind_rep\n"); + $found_err= 1; } } + + return $found_err; } # From e2436cb92c9a1723314d0930430ff9aa19a79528 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 24 Nov 2010 21:23:41 +0100 Subject: [PATCH 014/110] Bug #58411 :wixca project fails to build when using Express Edition of VS: The problem was MFC header file includes into the resource definition file (CustomAction.rc) afxres.h is not available with VS Express. The fix is to remove resource file from compilation and souce code repository. version of custom action dll is of no interest for anyone, it is internal dll kept inside the MSI. --- packaging/WiX/ca/CMakeLists.txt | 2 +- packaging/WiX/ca/CustomAction.rc | 18 ------------------ 2 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 packaging/WiX/ca/CustomAction.rc diff --git a/packaging/WiX/ca/CMakeLists.txt b/packaging/WiX/ca/CMakeLists.txt index c74b51284c7..a03ceb9a5d2 100644 --- a/packaging/WiX/ca/CMakeLists.txt +++ b/packaging/WiX/ca/CMakeLists.txt @@ -16,7 +16,7 @@ INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/inc) LINK_DIRECTORIES(${WIX_DIR}/../SDK/lib) -SET(WIXCA_SOURCES CustomAction.cpp CustomAction.rc CustomAction.def) +SET(WIXCA_SOURCES CustomAction.cpp CustomAction.def) IF(CMAKE_SIZEOF_VOID_P EQUAL 8) LINK_LIBRARIES(wcautil_x64 dutil_x64 msi version) diff --git a/packaging/WiX/ca/CustomAction.rc b/packaging/WiX/ca/CustomAction.rc deleted file mode 100644 index 3f37126ee77..00000000000 --- a/packaging/WiX/ca/CustomAction.rc +++ /dev/null @@ -1,18 +0,0 @@ -#include "afxres.h" -#undef APSTUDIO_READONLY_SYMBOLS - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x0L - FILESUBTYPE 0x0L -BEGIN -END - From a2505e9768e5a7a083efb6f8281684d3ed36f059 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 24 Nov 2010 21:30:27 +0100 Subject: [PATCH 015/110] MSI: Only call custom action if REMOVE=ALL is specified, this avoids accidential removing services if feature states are modified (reported by Iggy) --- packaging/WiX/mysql_server.wxs.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/WiX/mysql_server.wxs.in b/packaging/WiX/mysql_server.wxs.in index ea2ee1d9aaf..43a30538384 100644 --- a/packaging/WiX/mysql_server.wxs.in +++ b/packaging/WiX/mysql_server.wxs.in @@ -128,10 +128,10 @@ Impersonate="no" Return="check" /> - Installed And Not UPGRADINGPRODUCTCODE - Installed And Not UPGRADINGPRODUCTCODE - Installed And Not UPGRADINGPRODUCTCODE And UILevel>4 - Installed And Not UPGRADINGPRODUCTCODE And UILevel<=4 + Installed And Not UPGRADINGPRODUCTCODE And REMOVE="ALL" + Installed And Not UPGRADINGPRODUCTCODE And REMOVE="ALL" + Installed And Not UPGRADINGPRODUCTCODE And REMOVE="ALL" And UILevel>4 + Installed And Not UPGRADINGPRODUCTCODE And REMOVE="ALL" And UILevel<=4 From f2d0f9c5f84b4a3c9a2bf80afdf000f1cc7fc22c Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 24 Nov 2010 23:34:00 +0000 Subject: [PATCH 016/110] Support alternate license file. --- packaging/WiX/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packaging/WiX/CMakeLists.txt b/packaging/WiX/CMakeLists.txt index 052887f10a1..4048273fc03 100644 --- a/packaging/WiX/CMakeLists.txt +++ b/packaging/WiX/CMakeLists.txt @@ -63,7 +63,12 @@ FIND_PROGRAM(LIGHT_EXECUTABLE light ${WIX_DIR}) IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.rtf") SET(COPYING_RTF "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.rtf") ELSE() - FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/../../COPYING" CONTENTS) + IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../LICENSE.mysql") + SET(LICENSE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../../LICENSE.mysql") + ELSE() + SET(LICENSE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../../COPYING") + ENDIF() + FILE(READ ${LICENSE_FILE} CONTENTS) STRING(REGEX REPLACE "\n" "\\\\par\n" CONTENTS "${CONTENTS}") STRING(REGEX REPLACE "\t" "\\\\tab" CONTENTS "${CONTENTS}") FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}/COPYING.rtf" "{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0\\fnil\\fcharset0 Courier New;}}\\viewkind4\\uc1\\pard\\lang1031\\f0\\fs15") From 3afaada70dfd3831b38d601d89d5e20b444fc645 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 25 Nov 2010 00:20:36 +0000 Subject: [PATCH 017/110] Post-fix for Bug#58158 on Solaris Problem : The build might fail with make[2]: *** No rule to make target `../sql/z', needed by `sql/mysqld_dtrace_all.o'. Stop. if one of plugins would depends on system libz library Fix: Filter out non-static dependent libraries when dtracing static libs --- cmake/dtrace.cmake | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake index c12a74cba31..5beb45ca524 100644 --- a/cmake/dtrace.cmake +++ b/cmake/dtrace.cmake @@ -153,13 +153,23 @@ ENDFUNCTION() # to mysqld. MACRO (DTRACE_INSTRUMENT_STATIC_LIBS target libs) IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND ENABLE_DTRACE) + # Filter out non-static libraries in the list, if any + SET(static_libs) FOREACH(lib ${libs}) + GET_TARGET_PROPERTY(libtype ${lib} TYPE) + IF(libtype MATCHES STATIC_LIBRARY) + SET(static_libs ${static_lics} ${lib}) + ENDIF() + ENDFOREACH() + + FOREACH(lib ${static_libs}) SET(dirs ${dirs} ${TARGET_OBJECT_DIRECTORY_${lib}}) ENDFOREACH() + SET (obj ${CMAKE_CURRENT_BINARY_DIR}/${target}_dtrace_all.o) ADD_CUSTOM_COMMAND( OUTPUT ${obj} - DEPENDS ${libs} + DEPENDS ${static_libs} COMMAND ${CMAKE_COMMAND} -DDTRACE=${DTRACE} -DOUTFILE=${obj} From ddbcb7b5c4c9ea0dbac946eac5df82cb14dcbd01 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 25 Nov 2010 00:21:28 +0000 Subject: [PATCH 018/110] Fix the .deb package prefix. --- cmake/install_layout.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 19a8a61df2d..601e208d96d 100644 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -26,7 +26,7 @@ # Build as per default RPM layout, with prefix=/usr # # DEB -# Build as per STANDALONE, prefix=/opt/mysql-$major.$minor +# Build as per STANDALONE, prefix=/opt/mysql/server-$major.$minor # # SVR4 # Solaris package layout suitable for pkg* tools, prefix=/opt/mysql/mysql @@ -74,7 +74,7 @@ IF(UNIX) IF(INSTALL_LAYOUT MATCHES "RPM") SET(default_prefix "/usr") ELSEIF(INSTALL_LAYOUT MATCHES "DEB") - SET(default_prefix "/opt/${MYSQL_BASE_VERSION}") + SET(default_prefix "/opt/mysql/server-${MYSQL_BASE_VERSION}") # This is required to avoid "cpack -GDEB" default of prefix=/usr SET(CPACK_SET_DESTDIR ON) ELSEIF(INSTALL_LAYOUT MATCHES "SVR4") From 3a15cb6ce92fe9e7172f51991317cfbeb5307966 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Thu, 25 Nov 2010 03:11:05 +0000 Subject: [PATCH 019/110] Assorted post-merge fixes, clean-up, integration, compat with 5.6. 43233/55794. --- mysql-test/r/change_user.result | 2 +- mysql-test/r/key_cache.result | 3 +-- mysql-test/r/variables.result | 5 ++-- mysql-test/t/change_user.test | 2 +- mysql-test/t/key_cache.test | 1 + mysql-test/t/variables.test | 5 +++- sql/mysqld.cc | 2 +- sql/set_var.cc | 43 ++------------------------------- tests/mysql_client_test.c | 4 +-- 9 files changed, 15 insertions(+), 52 deletions(-) diff --git a/mysql-test/r/change_user.result b/mysql-test/r/change_user.result index f8d5d900a80..1ed7fcbb8fa 100644 --- a/mysql-test/r/change_user.result +++ b/mysql-test/r/change_user.result @@ -18,7 +18,7 @@ change_user SELECT @@session.sql_big_selects; @@session.sql_big_selects 0 -SET @@global.max_join_size = -1; +SET @@global.max_join_size = 18446744073709551615; SET @@session.max_join_size = default; change_user SELECT @@session.sql_big_selects; diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index 08d8059f61b..f80fea0fc76 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -334,8 +334,7 @@ test.t1 check status OK DROP TABLE t1,t2; set global key_cache_block_size= @my_key_cache_block_size; set @@global.key_buffer_size=0; -Warnings: -Warning 1438 Cannot drop default keycache +ERROR HY000: Cannot drop default keycache select @@global.key_buffer_size; @@global.key_buffer_size 2097152 diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 58f88b78bda..20f41c4a83c 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1524,7 +1524,7 @@ ERROR 42000: Variable 'max_binlog_cache_size' can't be set to the value of '-1' SET @@global.max_join_size=0; ERROR 42000: Variable 'max_join_size' can't be set to the value of '0' SET @@global.key_buffer_size=0; -ERROR 42000: Variable 'key_buffer_size' can't be set to the value of '0' +ERROR HY000: Cannot drop default keycache SET @@global.key_cache_block_size=0; ERROR 42000: Variable 'key_cache_block_size' can't be set to the value of '0' throw warnings in default mode @@ -1536,8 +1536,7 @@ SET @@global.max_join_size=0; Warnings: Warning 1292 Truncated incorrect max_join_size value: '0' SET @@global.key_buffer_size=0; -Warnings: -Warning 1292 Truncated incorrect key_buffer_size value: '0' +ERROR HY000: Cannot drop default keycache SET @@global.key_cache_block_size=0; Warnings: Warning 1292 Truncated incorrect key_cache_block_size value: '0' diff --git a/mysql-test/t/change_user.test b/mysql-test/t/change_user.test index 89f35116a2c..3ed798e8d36 100644 --- a/mysql-test/t/change_user.test +++ b/mysql-test/t/change_user.test @@ -20,7 +20,7 @@ SET @@session.max_join_size = default; SELECT @@session.sql_big_selects; # On some machines the following will result into a warning --disable_warnings -SET @@global.max_join_size = -1; +SET @@global.max_join_size = 18446744073709551615; --enable_warnings SET @@session.max_join_size = default; --echo change_user diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index 4c14dc96aaa..f12d20e962e 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -216,6 +216,7 @@ set global key_cache_block_size= @my_key_cache_block_size; # Bug#10473 - Can't set 'key_buffer_size' system variable to ZERO # (One cannot drop the default key cache.) # +--error ER_WARN_CANT_DROP_DEFAULT_KEYCACHE set @@global.key_buffer_size=0; select @@global.key_buffer_size; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 1b411d9420c..74d5c8450a2 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -1275,7 +1275,7 @@ SET @@global.max_binlog_cache_size=-1; SET @@global.max_join_size=0; # sys_var_key_buffer_size: "key_buffer_size" ---error ER_WRONG_VALUE_FOR_VAR +--error ER_WARN_CANT_DROP_DEFAULT_KEYCACHE SET @@global.key_buffer_size=0; # sys_var_key_cache_long: "key_cache_block_size" et al. @@ -1287,6 +1287,9 @@ SET SQL_MODE=DEFAULT; SET @@global.max_binlog_cache_size=-1; SET @@global.max_join_size=0; +# this is an exception. since this is a new error/warning, let's stay +# compatible with the upcoming 5.6. +--error ER_WARN_CANT_DROP_DEFAULT_KEYCACHE SET @@global.key_buffer_size=0; SET @@global.key_cache_block_size=0; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d17ccc47abb..98556e87838 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6774,7 +6774,7 @@ thread is in the relay logs.", "as much as you can afford; 1GB on a 4GB machine that mainly runs MySQL is " "quite common.", &dflt_key_cache_var.param_buff_size, NULL, NULL, (GET_ULL | GET_ASK_ADDR), - REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, SIZE_T_MAX, MALLOC_OVERHEAD, + REQUIRED_ARG, KEY_CACHE_SIZE, 0, SIZE_T_MAX, MALLOC_OVERHEAD, IO_SIZE, 0}, {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD, "This characterizes the number of hits a hot block has to be untouched " diff --git a/sql/set_var.cc b/sql/set_var.cc index 2621c8457bc..26f97d46d52 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1423,44 +1423,6 @@ bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd, } -/** - check an unsigned user-supplied value for a systemvariable against bounds. - - TODO: This is a wrapper function to call clipping from within an update() - function. Calling bounds from within update() is fair game in theory, - but we can only send warnings from in there, not errors, and besides, - it violates our model of separating check from update phase. - To avoid breaking out of the server with an ASSERT() in strict mode, - we pretend we're not in strict mode when we go through here. Bug#43233 - was opened to remind us to replace this kludge with The Right Thing, - which of course is to do the check in the actual check phase, and then - throw an error or warning accordingly. - - @param thd thread handle - @param num the value to limit - @param option_limits the bounds-record, or NULL if none - */ -static void bound_unsigned(THD *thd, ulonglong *num, - const struct my_option *option_limits) -{ - if (option_limits) - { - my_bool fixed = FALSE; - ulonglong unadjusted= *num; - - *num= getopt_ull_limit_value(unadjusted, option_limits, &fixed); - - if (fixed) - { - ulong ssm= thd->variables.sql_mode; - thd->variables.sql_mode&= ~MODE_STRICT_ALL_TABLES; - throw_bounds_warning(thd, fixed, TRUE, option_limits->name, unadjusted); - thd->variables.sql_mode= ssm; - } - } -} - - /** Get unsigned system-variable. Negative value does not wrap around, but becomes zero. @@ -2359,9 +2321,8 @@ bool sys_var_key_buffer_size::update(THD *thd, set_var *var) { if (key_cache == dflt_key_cache) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_CANT_DROP_DEFAULT_KEYCACHE, - ER(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE)); + error= 1; + my_error(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE, MYF(0)); goto end; // Ignore default key cache } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index ed8031b3fc3..53e2ed1d082 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -17125,7 +17125,7 @@ static void test_bug20023() /* Set MAX_JOIN_SIZE to the default value (-1). */ - DIE_IF(mysql_query(&con, "SET @@global.max_join_size = -1")); + DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 18446744073709551615")); DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default")); /* Issue COM_CHANGE_USER. */ @@ -17156,7 +17156,7 @@ static void test_bug20023() DIE_IF(mysql_query(&con, query_buffer)); - DIE_IF(mysql_query(&con, "SET @@global.max_join_size = -1")); + DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 18446744073709551615")); DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default")); /* Issue COM_CHANGE_USER. */ From 08c9f317eeaefd864186ec12ef82d9c57f516013 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 25 Nov 2010 10:28:36 +0100 Subject: [PATCH 020/110] Test sys_vars.shared_memory_base_name_basic used wrong path --- .../sys_vars/r/shared_memory_base_name_basic.result | 10 +++++----- .../sys_vars/t/shared_memory_base_name_basic.test | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/shared_memory_base_name_basic.result b/mysql-test/suite/sys_vars/r/shared_memory_base_name_basic.result index a94a906e121..356b3c9e879 100644 --- a/mysql-test/suite/sys_vars/r/shared_memory_base_name_basic.result +++ b/mysql-test/suite/sys_vars/r/shared_memory_base_name_basic.result @@ -1,20 +1,20 @@ select @@global.shared_memory_base_name; @@global.shared_memory_base_name -MYSQLTEST_VARDIR/tmp/mysqld.1.sock +MYSQL_TMP_DIR/mysqld.1.sock select @@session.shared_memory_base_name; ERROR HY000: Variable 'shared_memory_base_name' is a GLOBAL variable show global variables like 'shared_memory_base_name'; Variable_name Value -shared_memory_base_name MYSQLTEST_VARDIR/tmp/mysqld.1.sock +shared_memory_base_name MYSQL_TMP_DIR/mysqld.1.sock show session variables like 'shared_memory_base_name'; Variable_name Value -shared_memory_base_name MYSQLTEST_VARDIR/tmp/mysqld.1.sock +shared_memory_base_name MYSQL_TMP_DIR/mysqld.1.sock select * from information_schema.global_variables where variable_name='shared_memory_base_name'; VARIABLE_NAME VARIABLE_VALUE -SHARED_MEMORY_BASE_NAME MYSQLTEST_VARDIR/tmp/mysqld.1.sock +SHARED_MEMORY_BASE_NAME MYSQL_TMP_DIR/mysqld.1.sock select * from information_schema.session_variables where variable_name='shared_memory_base_name'; VARIABLE_NAME VARIABLE_VALUE -SHARED_MEMORY_BASE_NAME MYSQLTEST_VARDIR/tmp/mysqld.1.sock +SHARED_MEMORY_BASE_NAME MYSQL_TMP_DIR/mysqld.1.sock set global shared_memory_base_name=1; ERROR HY000: Variable 'shared_memory_base_name' is a read only variable set session shared_memory_base_name=1; diff --git a/mysql-test/suite/sys_vars/t/shared_memory_base_name_basic.test b/mysql-test/suite/sys_vars/t/shared_memory_base_name_basic.test index 24418a78687..da165564791 100644 --- a/mysql-test/suite/sys_vars/t/shared_memory_base_name_basic.test +++ b/mysql-test/suite/sys_vars/t/shared_memory_base_name_basic.test @@ -3,17 +3,17 @@ # # only global # ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR select @@global.shared_memory_base_name; --error ER_INCORRECT_GLOBAL_LOCAL_VAR select @@session.shared_memory_base_name; ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR show global variables like 'shared_memory_base_name'; ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR show session variables like 'shared_memory_base_name'; ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR select * from information_schema.global_variables where variable_name='shared_memory_base_name'; ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR select * from information_schema.session_variables where variable_name='shared_memory_base_name'; # From c639254274faf219d51437f40d1d762d2ec06d31 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 25 Nov 2010 13:43:58 +0100 Subject: [PATCH 021/110] Bug #58482 mtr doesn't use suite names from individually specified test cases It does work in general, the problem here was that the test name 'alter_table' matches 'main.alter_table-big' which has already been found. Fixed by matching more explicitly (with/without suite name) --- mysql-test/lib/mtr_cases.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 7961fa6fa7d..ece6c61ee1d 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -143,7 +143,7 @@ sub collect_test_cases ($$$) { { last unless $opt_reorder; # test->{name} is always in suite.name format - if ( $test->{name} =~ /.*\.$tname/ ) + if ( $test->{name} =~ /^$sname.*\.$tname$/ ) { $found= 1; last; From 20851e401265e6203aed6a5d979e9ac89e93f5d5 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 26 Nov 2010 10:57:01 +0100 Subject: [PATCH 022/110] Bug #58412 mysqltest: allow quoting of strings in let and in if comparison Stripping quotes in let was a bad idea, will not fix Added code to strip quotes from rhs in comparisons --- client/mysqltest.cc | 11 +++++++++++ .../rpl_tests/rpl_implicit_commit_binlog.test | 14 +++++++------- mysql-test/r/mysqltest.result | 3 +++ mysql-test/t/mysqltest.test | 14 +++++++++++++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 459abf8ffe1..dfd383cc714 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5678,6 +5678,17 @@ void do_block(enum block_cmd cmd, struct st_command* command) while (my_isspace(charset_info, *curr_ptr)) curr_ptr++; + /* Strip off trailing white space */ + while (my_isspace(charset_info, expr_end[-1])) + expr_end--; + /* strip off ' or " around the string */ + if (*curr_ptr == '\'' || *curr_ptr == '"') + { + if (expr_end[-1] != *curr_ptr) + die("Unterminated string value"); + curr_ptr++; + expr_end--; + } VAR v2; var_init(&v2,0,0,0,0); eval_expr(&v2, curr_ptr, &expr_end); diff --git a/mysql-test/extra/rpl_tests/rpl_implicit_commit_binlog.test b/mysql-test/extra/rpl_tests/rpl_implicit_commit_binlog.test index bbd4969ef40..172483e1466 100644 --- a/mysql-test/extra/rpl_tests/rpl_implicit_commit_binlog.test +++ b/mysql-test/extra/rpl_tests/rpl_implicit_commit_binlog.test @@ -36,8 +36,8 @@ let $ddl_cases= 41; while ($ddl_cases >= 1) { --echo -b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b- - let $in_temporary= "no"; - let $ok= "yes"; + let $in_temporary= no; + let $ok= yes; # # In SBR and MIXED modes, the commit event is usually the third event in the # binary log: @@ -91,7 +91,7 @@ while ($ddl_cases >= 1) { # This seems to be related to epochs. # We need to check this against an updated version or avoid it. - let $ok= "no"; + let $ok= no; let $commit_event_row_number= 6; } } @@ -356,7 +356,7 @@ while ($ddl_cases >= 1) if ($ddl_cases == 11) { let $cmd= CREATE TEMPORARY TABLE tt_xx (a int); - let $in_temporary= "yes"; + let $in_temporary= yes; # In SBR and MIXED modes, the DDL statement is written to the binary log but # does not commit the current transaction. # @@ -478,7 +478,7 @@ while ($ddl_cases >= 1) if ($ddl_cases == 8) { let $cmd= DROP TEMPORARY TABLE IF EXISTS new_tt_xx; - let $in_temporary= "yes"; + let $in_temporary= yes; # # In SBR and MIXED modes, the DDL statement is written to the binary log # but does not commit the current transaction: @@ -618,14 +618,14 @@ while ($ddl_cases >= 1) # commit. The flag in_temporary is used to avoid aborting the test in such # cases. Thus we force the commit. # - if ($in_temporary == "yes") + if ($in_temporary == yes) { --eval COMMIT } let $event_commit= query_get_value("SHOW BINLOG EVENTS FROM $first_binlog_position", Info, $commit_event_row_number); if (`SELECT SUBSTRING("$event_commit",1,6) != "COMMIT"`) { - if ($ok == "yes") + if ($ok == yes) { --echo it *does not* commit the current transaction. --echo $cmd diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index f5dce1e4196..6892164c225 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -423,7 +423,10 @@ while with string, only once hello == hello hello == hello hello != goodbye +'quoted' == ''quoted'' two words +'two words' +"two words" two words are two words right answer anything goes diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index cde517be03a..186b0e0fbfa 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1276,12 +1276,24 @@ if ($ifvar != goodbye) { echo hello != goodbye; } - +let $ifvar= 'quoted'; +if ($ifvar == ''quoted'') +{ + echo 'quoted' == ''quoted''; +} let $ifvar= two words; if ($ifvar == two words) { echo two words; } +if ($ifvar == 'two words') +{ + echo 'two words'; +} +if ($ifvar == "two words") +{ + echo "two words"; +} if ($ifvar == `SELECT 'two words'`) { echo two words are two words; From dce374bb663c0450546a6836cea763e8c3eca8dd Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 26 Nov 2010 12:24:05 +0200 Subject: [PATCH 023/110] bumped up the version string. --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 7fd581af009..9cfe342a7c5 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.54], [], [mysql]) +AC_INIT([MySQL Server], [5.1.55], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 93386d73876c6ff847d8f234b4933ac9d9b36f82 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 26 Nov 2010 13:44:39 +0300 Subject: [PATCH 024/110] Bug#57737 Character sets: search fails with like, contraction, index Problem: LIKE over an indexed column optimized away good results, because my_like_range_utf32/utf16 returned wrong ranges for contractions. Contraction related code was missing in my_like_range_utf32/utf16, but did exist in my_like_range_ucs2/utf8. It was forgotten in utf32/utf16 versions (during mysql-6.0 push/revert mess). Fix: The patch removes individual functions my_like_range_ucs2, my_like_range_utf16, my_like_range_utf32 and introduces a single function my_like_range_generic() instead. The new function handles contractions correctly. It can handle any character set with cs->min_sort_char and cs->max_sort_char represented in Unicode code points. added: @ mysql-test/include/ctype_czech.inc @ mysql-test/include/ctype_like_ignorable.inc @ mysql-test/r/ctype_like_range.result @ mysql-test/t/ctype_like_range.test Adding tests modified: @ include/m_ctype.h - Adding helper functions for contractions. - Prototypes: removing ucs2,utf16,utf32 functions, adding generic function. @ mysql-test/r/ctype_uca.result @ mysql-test/r/ctype_utf16_uca.result @ mysql-test/r/ctype_utf32_uca.result @ mysql-test/t/ctype_uca.test @ mysql-test/t/ctype_utf16_uca.test @ mysql-test/t/ctype_utf32_uca.test - Adding tests. @ strings/ctype-mb.c - Pad function did not put the last character. - Implementing my_like_range_generic() - an universal replacement for three separate functions my_like_range_ucs2(), my_like_range_utf16() and my_like_range_utf32(), with correct contraction handling. @ strings/ctype-ucs2.c - my_fill_mb2 did not put the high byte, as previously it was used to put only characters in ASCII range. Now it puts high byte as well (needed to pupulate cs->max_sort_char correctly). - Adding DBUG_ASSERT() - Removing character set specific functions: my_like_range_ucs2(), my_like_range_utf16() and my_like_range_utf32(). - Using my_like_range_generic() instead of the old functions. @ strings/ctype-uca.c - Using generic function instead of the old character set specific ones. @ sql/item_create.cc @ sql/item_strfunc.cc @ sql/item_strfunc.h - Adding SQL functions LIKE_RANGE_MIN and LIKE_RANGE_MAX, available only in debug build to make sure like_range() works correctly for all character sets and collations. --- include/m_ctype.h | 55 +- mysql-test/include/ctype_czech.inc | 12 + mysql-test/include/ctype_like_ignorable.inc | 11 + mysql-test/r/ctype_like_range.result | 2310 +++++++++++++++++++ mysql-test/r/ctype_uca.result | 98 + mysql-test/r/ctype_utf16_uca.result | 46 + mysql-test/r/ctype_utf32_uca.result | 46 + mysql-test/t/ctype_like_range.test | 87 + mysql-test/t/ctype_uca.test | 16 + mysql-test/t/ctype_utf16_uca.test | 7 + mysql-test/t/ctype_utf32_uca.test | 8 + sql/item_create.cc | 52 + sql/item_strfunc.cc | 35 + sql/item_strfunc.h | 40 + strings/ctype-mb.c | 188 +- strings/ctype-uca.c | 6 +- strings/ctype-ucs2.c | 328 +-- 17 files changed, 3001 insertions(+), 344 deletions(-) create mode 100644 mysql-test/include/ctype_czech.inc create mode 100644 mysql-test/include/ctype_like_ignorable.inc create mode 100644 mysql-test/r/ctype_like_range.result create mode 100644 mysql-test/t/ctype_like_range.test diff --git a/include/m_ctype.h b/include/m_ctype.h index 42e8f88cc0e..c054de8d7fd 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -356,6 +356,32 @@ extern CHARSET_INFO my_charset_utf8mb4_unicode_ci; #define MY_UTF8MB4 "utf8mb4" +/* Helper functions to handle contraction */ +static inline my_bool +my_cs_have_contractions(CHARSET_INFO *cs) +{ + return cs->contractions != NULL; +} + +static inline my_bool +my_cs_can_be_contraction_head(CHARSET_INFO *cs, my_wc_t wc) +{ + return ((const char *)cs->contractions)[0x40*0x40 + (wc & 0xFF)]; +} + +static inline my_bool +my_cs_can_be_contraction_tail(CHARSET_INFO *cs, my_wc_t wc) +{ + return ((const char *)cs->contractions)[0x40*0x40 + (wc & 0xFF)]; +} + +static inline uint16* +my_cs_contraction2_weight(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2) +{ + return &cs->contractions[(wc1 - 0x40) * 0x40 + wc2 - 0x40]; +} + + /* declarations for simple charsets */ extern size_t my_strnxfrm_simple(CHARSET_INFO *, uchar *, size_t, const uchar *, size_t); @@ -430,6 +456,7 @@ ulonglong my_strntoull10rnd_ucs2(CHARSET_INFO *cs, void my_fill_8bit(CHARSET_INFO *cs, char* to, size_t l, int fill); +/* For 8-bit character set */ my_bool my_like_range_simple(CHARSET_INFO *cs, const char *ptr, size_t ptr_length, pbool escape, pbool w_one, pbool w_many, @@ -437,6 +464,7 @@ my_bool my_like_range_simple(CHARSET_INFO *cs, char *min_str, char *max_str, size_t *min_length, size_t *max_length); +/* For ASCII-based multi-byte character sets with mbminlen=1 */ my_bool my_like_range_mb(CHARSET_INFO *cs, const char *ptr, size_t ptr_length, pbool escape, pbool w_one, pbool w_many, @@ -444,26 +472,13 @@ my_bool my_like_range_mb(CHARSET_INFO *cs, char *min_str, char *max_str, size_t *min_length, size_t *max_length); -my_bool my_like_range_ucs2(CHARSET_INFO *cs, - const char *ptr, size_t ptr_length, - pbool escape, pbool w_one, pbool w_many, - size_t res_length, - char *min_str, char *max_str, - size_t *min_length, size_t *max_length); - -my_bool my_like_range_utf16(CHARSET_INFO *cs, - const char *ptr, size_t ptr_length, - pbool escape, pbool w_one, pbool w_many, - size_t res_length, - char *min_str, char *max_str, - size_t *min_length, size_t *max_length); - -my_bool my_like_range_utf32(CHARSET_INFO *cs, - const char *ptr, size_t ptr_length, - pbool escape, pbool w_one, pbool w_many, - size_t res_length, - char *min_str, char *max_str, - size_t *min_length, size_t *max_length); +/* For other character sets, with arbitrary mbminlen and mbmaxlen numbers */ +my_bool my_like_range_generic(CHARSET_INFO *cs, + const char *ptr, size_t ptr_length, + pbool escape, pbool w_one, pbool w_many, + size_t res_length, + char *min_str, char *max_str, + size_t *min_length, size_t *max_length); int my_wildcmp_8bit(CHARSET_INFO *, const char *str,const char *str_end, diff --git a/mysql-test/include/ctype_czech.inc b/mysql-test/include/ctype_czech.inc new file mode 100644 index 00000000000..bc83d462a22 --- /dev/null +++ b/mysql-test/include/ctype_czech.inc @@ -0,0 +1,12 @@ +SELECT @@collation_connection; +--echo # +--echo # Bug#57737 Character sets: search fails with like, contraction, index +--echo # +CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS s1 LIMIT 0; +INSERT INTO t1 VALUES ('c'),('ce'),('cé'),('ch'); +SELECT * FROM t1 WHERE s1 LIKE 'c%'; +ALTER TABLE t1 ADD KEY s1 (s1); +SELECT * FROM t1 WHERE s1 LIKE 'c%'; +ALTER TABLE t1 DROP KEY s1, ADD KEY(s1(1)); +SELECT * FROM t1 WHERE s1 LIKE 'ch'; +DROP TABLE t1; diff --git a/mysql-test/include/ctype_like_ignorable.inc b/mysql-test/include/ctype_like_ignorable.inc new file mode 100644 index 00000000000..9f2fa7ae741 --- /dev/null +++ b/mysql-test/include/ctype_like_ignorable.inc @@ -0,0 +1,11 @@ +SELECT @@collation_connection; +--echo # +--echo # Bug#57737 Character sets: search fails with like, contraction, index +--echo # Part#2 - ignorable characters +--echo # +CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS s1 LIMIT 0; +INSERT INTO t1 VALUES ('a\0\0\0\0\0\t'),('a'),('b'),('c'),('d'),('e'); +SELECT HEX(s1) FROM t1 WHERE s1 LIKE 'a%'; +ALTER TABLE t1 ADD KEY s1 (s1); +SELECT HEX(s1) FROM t1 WHERE s1 LIKE 'a%'; +DROP TABLE t1; diff --git a/mysql-test/r/ctype_like_range.result b/mysql-test/r/ctype_like_range.result new file mode 100644 index 00000000000..a06c6ad9ed8 --- /dev/null +++ b/mysql-test/r/ctype_like_range.result @@ -0,0 +1,2310 @@ +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, a VARBINARY(32)); +INSERT INTO t1 (a) VALUES (''),('_'),('%'),('\_'),('\%'),('\\'); +INSERT INTO t1 (a) VALUES ('a'),('c'); +INSERT INTO t1 (a) VALUES ('a_'),('c_'); +INSERT INTO t1 (a) VALUES ('a%'),('c%'); +INSERT INTO t1 (a) VALUES ('aa'),('cc'),('ch'); +INSERT INTO t1 (a) VALUES ('aa_'),('cc_'),('ch_'); +INSERT INTO t1 (a) VALUES ('aa%'),('cc%'),('ch%'); +INSERT INTO t1 (a) VALUES ('aaa'),('ccc'),('cch'); +INSERT INTO t1 (a) VALUES ('aaa_'),('ccc_'),('cch_'); +INSERT INTO t1 (a) VALUES ('aaa%'),('ccc%'),('cch%'); +INSERT INTO t1 (a) VALUES ('aaaaaaaaaaaaaaaaaaaa'); +CREATE VIEW v1 AS +SELECT id, 'a' AS name, a AS val FROM t1 +UNION +SELECT id, 'mn', HEX(LIKE_RANGE_MIN(a, 16)) AS min FROM t1 +UNION +SELECT id, 'mx', HEX(LIKE_RANGE_MAX(a, 16)) AS max FROM t1 +UNION +SELECT id, 'sp', REPEAT('-', 32) AS sep FROM t1 +ORDER BY id, name; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 00 +2 mx FF +2 sp -------------------------------- +3 a % +3 mn +3 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +3 sp -------------------------------- +4 a \_ +4 mn 5F +4 mx 5F +4 sp -------------------------------- +5 a \% +5 mn 25 +5 mx 25 +5 sp -------------------------------- +6 a \ +6 mn 5C +6 mx 5C +6 sp -------------------------------- +7 a a +7 mn 61 +7 mx 61 +7 sp -------------------------------- +8 a c +8 mn 63 +8 mx 63 +8 sp -------------------------------- +9 a a_ +9 mn 6100 +9 mx 61FF +9 sp -------------------------------- +10 a c_ +10 mn 6300 +10 mx 63FF +10 sp -------------------------------- +11 a a% +11 mn 61 +11 mx 61FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +11 sp -------------------------------- +12 a c% +12 mn 63 +12 mx 63FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +12 sp -------------------------------- +13 a aa +13 mn 6161 +13 mx 6161 +13 sp -------------------------------- +14 a cc +14 mn 6363 +14 mx 6363 +14 sp -------------------------------- +15 a ch +15 mn 6368 +15 mx 6368 +15 sp -------------------------------- +16 a aa_ +16 mn 616100 +16 mx 6161FF +16 sp -------------------------------- +17 a cc_ +17 mn 636300 +17 mx 6363FF +17 sp -------------------------------- +18 a ch_ +18 mn 636800 +18 mx 6368FF +18 sp -------------------------------- +19 a aa% +19 mn 6161 +19 mx 6161FFFFFFFFFFFFFFFFFFFFFFFFFFFF +19 sp -------------------------------- +20 a cc% +20 mn 6363 +20 mx 6363FFFFFFFFFFFFFFFFFFFFFFFFFFFF +20 sp -------------------------------- +21 a ch% +21 mn 6368 +21 mx 6368FFFFFFFFFFFFFFFFFFFFFFFFFFFF +21 sp -------------------------------- +22 a aaa +22 mn 616161 +22 mx 616161 +22 sp -------------------------------- +23 a ccc +23 mn 636363 +23 mx 636363 +23 sp -------------------------------- +24 a cch +24 mn 636368 +24 mx 636368 +24 sp -------------------------------- +25 a aaa_ +25 mn 61616100 +25 mx 616161FF +25 sp -------------------------------- +26 a ccc_ +26 mn 63636300 +26 mx 636363FF +26 sp -------------------------------- +27 a cch_ +27 mn 63636800 +27 mx 636368FF +27 sp -------------------------------- +28 a aaa% +28 mn 616161 +28 mx 616161FFFFFFFFFFFFFFFFFFFFFFFFFF +28 sp -------------------------------- +29 a ccc% +29 mn 636363 +29 mx 636363FFFFFFFFFFFFFFFFFFFFFFFFFF +29 sp -------------------------------- +30 a cch% +30 mn 636368 +30 mx 636368FFFFFFFFFFFFFFFFFFFFFFFFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 61616161616161616161616161616161 +31 mx 61616161616161616161616161616161 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET latin1; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 00 +2 mx FF +2 sp -------------------------------- +3 a % +3 mn 00000000000000000000000000000000 +3 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +3 sp -------------------------------- +4 a \_ +4 mn 5F +4 mx 5F +4 sp -------------------------------- +5 a \% +5 mn 25 +5 mx 25 +5 sp -------------------------------- +6 a \ +6 mn 5C +6 mx 5C +6 sp -------------------------------- +7 a a +7 mn 61 +7 mx 61 +7 sp -------------------------------- +8 a c +8 mn 63 +8 mx 63 +8 sp -------------------------------- +9 a a_ +9 mn 6100 +9 mx 61FF +9 sp -------------------------------- +10 a c_ +10 mn 6300 +10 mx 63FF +10 sp -------------------------------- +11 a a% +11 mn 61000000000000000000000000000000 +11 mx 61FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +11 sp -------------------------------- +12 a c% +12 mn 63000000000000000000000000000000 +12 mx 63FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +12 sp -------------------------------- +13 a aa +13 mn 6161 +13 mx 6161 +13 sp -------------------------------- +14 a cc +14 mn 6363 +14 mx 6363 +14 sp -------------------------------- +15 a ch +15 mn 6368 +15 mx 6368 +15 sp -------------------------------- +16 a aa_ +16 mn 616100 +16 mx 6161FF +16 sp -------------------------------- +17 a cc_ +17 mn 636300 +17 mx 6363FF +17 sp -------------------------------- +18 a ch_ +18 mn 636800 +18 mx 6368FF +18 sp -------------------------------- +19 a aa% +19 mn 61610000000000000000000000000000 +19 mx 6161FFFFFFFFFFFFFFFFFFFFFFFFFFFF +19 sp -------------------------------- +20 a cc% +20 mn 63630000000000000000000000000000 +20 mx 6363FFFFFFFFFFFFFFFFFFFFFFFFFFFF +20 sp -------------------------------- +21 a ch% +21 mn 63680000000000000000000000000000 +21 mx 6368FFFFFFFFFFFFFFFFFFFFFFFFFFFF +21 sp -------------------------------- +22 a aaa +22 mn 616161 +22 mx 616161 +22 sp -------------------------------- +23 a ccc +23 mn 636363 +23 mx 636363 +23 sp -------------------------------- +24 a cch +24 mn 636368 +24 mx 636368 +24 sp -------------------------------- +25 a aaa_ +25 mn 61616100 +25 mx 616161FF +25 sp -------------------------------- +26 a ccc_ +26 mn 63636300 +26 mx 636363FF +26 sp -------------------------------- +27 a cch_ +27 mn 63636800 +27 mx 636368FF +27 sp -------------------------------- +28 a aaa% +28 mn 61616100000000000000000000000000 +28 mx 616161FFFFFFFFFFFFFFFFFFFFFFFFFF +28 sp -------------------------------- +29 a ccc% +29 mn 63636300000000000000000000000000 +29 mx 636363FFFFFFFFFFFFFFFFFFFFFFFFFF +29 sp -------------------------------- +30 a cch% +30 mn 63636800000000000000000000000000 +30 mx 636368FFFFFFFFFFFFFFFFFFFFFFFFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 61616161616161616161616161616161 +31 mx 61616161616161616161616161616161 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf8; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 00000000000000000000000000000000 +2 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +2 sp -------------------------------- +3 a % +3 mn 00000000000000000000000000000000 +3 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +3 sp -------------------------------- +4 a \_ +4 mn 5F +4 mx 5F +4 sp -------------------------------- +5 a \% +5 mn 25 +5 mx 25 +5 sp -------------------------------- +6 a \ +6 mn 5C +6 mx 5C +6 sp -------------------------------- +7 a a +7 mn 61 +7 mx 61 +7 sp -------------------------------- +8 a c +8 mn 63 +8 mx 63 +8 sp -------------------------------- +9 a a_ +9 mn 61000000000000000000000000000000 +9 mx 61EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +9 sp -------------------------------- +10 a c_ +10 mn 63000000000000000000000000000000 +10 mx 63EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +10 sp -------------------------------- +11 a a% +11 mn 61000000000000000000000000000000 +11 mx 61EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +11 sp -------------------------------- +12 a c% +12 mn 63000000000000000000000000000000 +12 mx 63EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +12 sp -------------------------------- +13 a aa +13 mn 6161 +13 mx 6161 +13 sp -------------------------------- +14 a cc +14 mn 6363 +14 mx 6363 +14 sp -------------------------------- +15 a ch +15 mn 6368 +15 mx 6368 +15 sp -------------------------------- +16 a aa_ +16 mn 61610000000000000000000000000000 +16 mx 6161EFBFBFEFBFBFEFBFBFEFBFBF2020 +16 sp -------------------------------- +17 a cc_ +17 mn 63630000000000000000000000000000 +17 mx 6363EFBFBFEFBFBFEFBFBFEFBFBF2020 +17 sp -------------------------------- +18 a ch_ +18 mn 63680000000000000000000000000000 +18 mx 6368EFBFBFEFBFBFEFBFBFEFBFBF2020 +18 sp -------------------------------- +19 a aa% +19 mn 61610000000000000000000000000000 +19 mx 6161EFBFBFEFBFBFEFBFBFEFBFBF2020 +19 sp -------------------------------- +20 a cc% +20 mn 63630000000000000000000000000000 +20 mx 6363EFBFBFEFBFBFEFBFBFEFBFBF2020 +20 sp -------------------------------- +21 a ch% +21 mn 63680000000000000000000000000000 +21 mx 6368EFBFBFEFBFBFEFBFBFEFBFBF2020 +21 sp -------------------------------- +22 a aaa +22 mn 616161 +22 mx 616161 +22 sp -------------------------------- +23 a ccc +23 mn 636363 +23 mx 636363 +23 sp -------------------------------- +24 a cch +24 mn 636368 +24 mx 636368 +24 sp -------------------------------- +25 a aaa_ +25 mn 61616100000000000000000000000000 +25 mx 616161EFBFBFEFBFBFEFBFBFEFBFBF20 +25 sp -------------------------------- +26 a ccc_ +26 mn 63636300000000000000000000000000 +26 mx 636363EFBFBFEFBFBFEFBFBFEFBFBF20 +26 sp -------------------------------- +27 a cch_ +27 mn 63636800000000000000000000000000 +27 mx 636368EFBFBFEFBFBFEFBFBFEFBFBF20 +27 sp -------------------------------- +28 a aaa% +28 mn 61616100000000000000000000000000 +28 mx 616161EFBFBFEFBFBFEFBFBFEFBFBF20 +28 sp -------------------------------- +29 a ccc% +29 mn 63636300000000000000000000000000 +29 mx 636363EFBFBFEFBFBFEFBFBFEFBFBF20 +29 sp -------------------------------- +30 a cch% +30 mn 63636800000000000000000000000000 +30 mx 636368EFBFBFEFBFBFEFBFBFEFBFBF20 +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 6161616161 +31 mx 6161616161 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 09090909090909090909090909090909 +2 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +2 sp -------------------------------- +3 a % +3 mn 09090909090909090909090909090909 +3 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +3 sp -------------------------------- +4 a \_ +4 mn 5F +4 mx 5F +4 sp -------------------------------- +5 a \% +5 mn 25 +5 mx 25 +5 sp -------------------------------- +6 a \ +6 mn 5C +6 mx 5C +6 sp -------------------------------- +7 a a +7 mn 61 +7 mx 61 +7 sp -------------------------------- +8 a c +8 mn 63 +8 mx 63 +8 sp -------------------------------- +9 a a_ +9 mn 61090909090909090909090909090909 +9 mx 61EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +9 sp -------------------------------- +10 a c_ +10 mn 63090909090909090909090909090909 +10 mx 63EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +10 sp -------------------------------- +11 a a% +11 mn 61090909090909090909090909090909 +11 mx 61EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +11 sp -------------------------------- +12 a c% +12 mn 63090909090909090909090909090909 +12 mx 63EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +12 sp -------------------------------- +13 a aa +13 mn 6161 +13 mx 6161 +13 sp -------------------------------- +14 a cc +14 mn 6363 +14 mx 6363 +14 sp -------------------------------- +15 a ch +15 mn 6368 +15 mx 6368 +15 sp -------------------------------- +16 a aa_ +16 mn 61610909090909090909090909090909 +16 mx 6161EFBFBFEFBFBFEFBFBFEFBFBF2020 +16 sp -------------------------------- +17 a cc_ +17 mn 63630909090909090909090909090909 +17 mx 6363EFBFBFEFBFBFEFBFBFEFBFBF2020 +17 sp -------------------------------- +18 a ch_ +18 mn 63680909090909090909090909090909 +18 mx 6368EFBFBFEFBFBFEFBFBFEFBFBF2020 +18 sp -------------------------------- +19 a aa% +19 mn 61610909090909090909090909090909 +19 mx 6161EFBFBFEFBFBFEFBFBFEFBFBF2020 +19 sp -------------------------------- +20 a cc% +20 mn 63630909090909090909090909090909 +20 mx 6363EFBFBFEFBFBFEFBFBFEFBFBF2020 +20 sp -------------------------------- +21 a ch% +21 mn 63680909090909090909090909090909 +21 mx 6368EFBFBFEFBFBFEFBFBFEFBFBF2020 +21 sp -------------------------------- +22 a aaa +22 mn 616161 +22 mx 616161 +22 sp -------------------------------- +23 a ccc +23 mn 636363 +23 mx 636363 +23 sp -------------------------------- +24 a cch +24 mn 636368 +24 mx 636368 +24 sp -------------------------------- +25 a aaa_ +25 mn 61616109090909090909090909090909 +25 mx 616161EFBFBFEFBFBFEFBFBFEFBFBF20 +25 sp -------------------------------- +26 a ccc_ +26 mn 63636309090909090909090909090909 +26 mx 636363EFBFBFEFBFBFEFBFBFEFBFBF20 +26 sp -------------------------------- +27 a cch_ +27 mn 63636809090909090909090909090909 +27 mx 636368EFBFBFEFBFBFEFBFBFEFBFBF20 +27 sp -------------------------------- +28 a aaa% +28 mn 61616109090909090909090909090909 +28 mx 616161EFBFBFEFBFBFEFBFBFEFBFBF20 +28 sp -------------------------------- +29 a ccc% +29 mn 63636309090909090909090909090909 +29 mx 636363EFBFBFEFBFBFEFBFBFEFBFBF20 +29 sp -------------------------------- +30 a cch% +30 mn 63636809090909090909090909090909 +30 mx 636368EFBFBFEFBFBFEFBFBFEFBFBF20 +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 6161616161 +31 mx 6161616161 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_czech_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 09090909090909090909090909090909 +2 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +2 sp -------------------------------- +3 a % +3 mn 09090909090909090909090909090909 +3 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +3 sp -------------------------------- +4 a \_ +4 mn 5F +4 mx 5F +4 sp -------------------------------- +5 a \% +5 mn 25 +5 mx 25 +5 sp -------------------------------- +6 a \ +6 mn 5C +6 mx 5C +6 sp -------------------------------- +7 a a +7 mn 61 +7 mx 61 +7 sp -------------------------------- +8 a c +8 mn 63 +8 mx 63 +8 sp -------------------------------- +9 a a_ +9 mn 61090909090909090909090909090909 +9 mx 61EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +9 sp -------------------------------- +10 a c_ +10 mn 09090909090909090909090909090909 +10 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +10 sp -------------------------------- +11 a a% +11 mn 61090909090909090909090909090909 +11 mx 61EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +11 sp -------------------------------- +12 a c% +12 mn 09090909090909090909090909090909 +12 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +12 sp -------------------------------- +13 a aa +13 mn 6161 +13 mx 6161 +13 sp -------------------------------- +14 a cc +14 mn 6363 +14 mx 6363 +14 sp -------------------------------- +15 a ch +15 mn 6368 +15 mx 6368 +15 sp -------------------------------- +16 a aa_ +16 mn 61610909090909090909090909090909 +16 mx 6161EFBFBFEFBFBFEFBFBFEFBFBF2020 +16 sp -------------------------------- +17 a cc_ +17 mn 63090909090909090909090909090909 +17 mx 63EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +17 sp -------------------------------- +18 a ch_ +18 mn 63680909090909090909090909090909 +18 mx 6368EFBFBFEFBFBFEFBFBFEFBFBF2020 +18 sp -------------------------------- +19 a aa% +19 mn 61610909090909090909090909090909 +19 mx 6161EFBFBFEFBFBFEFBFBFEFBFBF2020 +19 sp -------------------------------- +20 a cc% +20 mn 63090909090909090909090909090909 +20 mx 63EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +20 sp -------------------------------- +21 a ch% +21 mn 63680909090909090909090909090909 +21 mx 6368EFBFBFEFBFBFEFBFBFEFBFBF2020 +21 sp -------------------------------- +22 a aaa +22 mn 616161 +22 mx 616161 +22 sp -------------------------------- +23 a ccc +23 mn 636363 +23 mx 636363 +23 sp -------------------------------- +24 a cch +24 mn 636368 +24 mx 636368 +24 sp -------------------------------- +25 a aaa_ +25 mn 61616109090909090909090909090909 +25 mx 616161EFBFBFEFBFBFEFBFBFEFBFBF20 +25 sp -------------------------------- +26 a ccc_ +26 mn 63630909090909090909090909090909 +26 mx 6363EFBFBFEFBFBFEFBFBFEFBFBF2020 +26 sp -------------------------------- +27 a cch_ +27 mn 63636809090909090909090909090909 +27 mx 636368EFBFBFEFBFBFEFBFBFEFBFBF20 +27 sp -------------------------------- +28 a aaa% +28 mn 61616109090909090909090909090909 +28 mx 616161EFBFBFEFBFBFEFBFBFEFBFBF20 +28 sp -------------------------------- +29 a ccc% +29 mn 63630909090909090909090909090909 +29 mx 6363EFBFBFEFBFBFEFBFBFEFBFBF2020 +29 sp -------------------------------- +30 a cch% +30 mn 63636809090909090909090909090909 +30 mx 636368EFBFBFEFBFBFEFBFBFEFBFBF20 +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 6161616161 +31 mx 6161616161 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_danish_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 09090909090909090909090909090909 +2 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +2 sp -------------------------------- +3 a % +3 mn 09090909090909090909090909090909 +3 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +3 sp -------------------------------- +4 a \_ +4 mn 5F +4 mx 5F +4 sp -------------------------------- +5 a \% +5 mn 25 +5 mx 25 +5 sp -------------------------------- +6 a \ +6 mn 5C +6 mx 5C +6 sp -------------------------------- +7 a a +7 mn 61 +7 mx 61 +7 sp -------------------------------- +8 a c +8 mn 63 +8 mx 63 +8 sp -------------------------------- +9 a a_ +9 mn 09090909090909090909090909090909 +9 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +9 sp -------------------------------- +10 a c_ +10 mn 63090909090909090909090909090909 +10 mx 63EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +10 sp -------------------------------- +11 a a% +11 mn 09090909090909090909090909090909 +11 mx EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +11 sp -------------------------------- +12 a c% +12 mn 63090909090909090909090909090909 +12 mx 63EFBFBFEFBFBFEFBFBFEFBFBFEFBFBF +12 sp -------------------------------- +13 a aa +13 mn 6161 +13 mx 6161 +13 sp -------------------------------- +14 a cc +14 mn 6363 +14 mx 6363 +14 sp -------------------------------- +15 a ch +15 mn 6368 +15 mx 6368 +15 sp -------------------------------- +16 a aa_ +16 mn 61610909090909090909090909090909 +16 mx 6161EFBFBFEFBFBFEFBFBFEFBFBF2020 +16 sp -------------------------------- +17 a cc_ +17 mn 63630909090909090909090909090909 +17 mx 6363EFBFBFEFBFBFEFBFBFEFBFBF2020 +17 sp -------------------------------- +18 a ch_ +18 mn 63680909090909090909090909090909 +18 mx 6368EFBFBFEFBFBFEFBFBFEFBFBF2020 +18 sp -------------------------------- +19 a aa% +19 mn 61610909090909090909090909090909 +19 mx 6161EFBFBFEFBFBFEFBFBFEFBFBF2020 +19 sp -------------------------------- +20 a cc% +20 mn 63630909090909090909090909090909 +20 mx 6363EFBFBFEFBFBFEFBFBFEFBFBF2020 +20 sp -------------------------------- +21 a ch% +21 mn 63680909090909090909090909090909 +21 mx 6368EFBFBFEFBFBFEFBFBFEFBFBF2020 +21 sp -------------------------------- +22 a aaa +22 mn 616161 +22 mx 616161 +22 sp -------------------------------- +23 a ccc +23 mn 636363 +23 mx 636363 +23 sp -------------------------------- +24 a cch +24 mn 636368 +24 mx 636368 +24 sp -------------------------------- +25 a aaa_ +25 mn 61610909090909090909090909090909 +25 mx 6161EFBFBFEFBFBFEFBFBFEFBFBF2020 +25 sp -------------------------------- +26 a ccc_ +26 mn 63636309090909090909090909090909 +26 mx 636363EFBFBFEFBFBFEFBFBFEFBFBF20 +26 sp -------------------------------- +27 a cch_ +27 mn 63636809090909090909090909090909 +27 mx 636368EFBFBFEFBFBFEFBFBFEFBFBF20 +27 sp -------------------------------- +28 a aaa% +28 mn 61610909090909090909090909090909 +28 mx 6161EFBFBFEFBFBFEFBFBFEFBFBF2020 +28 sp -------------------------------- +29 a ccc% +29 mn 63636309090909090909090909090909 +29 mx 636363EFBFBFEFBFBFEFBFBFEFBFBF20 +29 sp -------------------------------- +30 a cch% +30 mn 63636809090909090909090909090909 +30 mx 636368EFBFBFEFBFBFEFBFBFEFBFBF20 +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 61616161090909090909090909090909 +31 mx 61616161EFBFBFEFBFBFEFBFBFEFBFBF +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET ucs2; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 0000 +2 mx FFFF +2 sp -------------------------------- +3 a % +3 mn 00000000000000000000000000000000 +3 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +3 sp -------------------------------- +4 a \_ +4 mn 005F +4 mx 005F +4 sp -------------------------------- +5 a \% +5 mn 0025 +5 mx 0025 +5 sp -------------------------------- +6 a \ +6 mn 005C +6 mx 005C +6 sp -------------------------------- +7 a a +7 mn 0061 +7 mx 0061 +7 sp -------------------------------- +8 a c +8 mn 0063 +8 mx 0063 +8 sp -------------------------------- +9 a a_ +9 mn 00610000 +9 mx 0061FFFF +9 sp -------------------------------- +10 a c_ +10 mn 00630000 +10 mx 0063FFFF +10 sp -------------------------------- +11 a a% +11 mn 00610000000000000000000000000000 +11 mx 0061FFFFFFFFFFFFFFFFFFFFFFFFFFFF +11 sp -------------------------------- +12 a c% +12 mn 00630000000000000000000000000000 +12 mx 0063FFFFFFFFFFFFFFFFFFFFFFFFFFFF +12 sp -------------------------------- +13 a aa +13 mn 00610061 +13 mx 00610061 +13 sp -------------------------------- +14 a cc +14 mn 00630063 +14 mx 00630063 +14 sp -------------------------------- +15 a ch +15 mn 00630068 +15 mx 00630068 +15 sp -------------------------------- +16 a aa_ +16 mn 006100610000 +16 mx 00610061FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 006300630000 +17 mx 00630063FFFF +17 sp -------------------------------- +18 a ch_ +18 mn 006300680000 +18 mx 00630068FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00610061000000000000000000000000 +19 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +19 sp -------------------------------- +20 a cc% +20 mn 00630063000000000000000000000000 +20 mx 00630063FFFFFFFFFFFFFFFFFFFFFFFF +20 sp -------------------------------- +21 a ch% +21 mn 00630068000000000000000000000000 +21 mx 00630068FFFFFFFFFFFFFFFFFFFFFFFF +21 sp -------------------------------- +22 a aaa +22 mn 006100610061 +22 mx 006100610061 +22 sp -------------------------------- +23 a ccc +23 mn 006300630063 +23 mx 006300630063 +23 sp -------------------------------- +24 a cch +24 mn 006300630068 +24 mx 006300630068 +24 sp -------------------------------- +25 a aaa_ +25 mn 0061006100610000 +25 mx 006100610061FFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 0063006300630000 +26 mx 006300630063FFFF +26 sp -------------------------------- +27 a cch_ +27 mn 0063006300680000 +27 mx 006300630068FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00610061006100000000000000000000 +28 mx 006100610061FFFFFFFFFFFFFFFFFFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00630063006300000000000000000000 +29 mx 006300630063FFFFFFFFFFFFFFFFFFFF +29 sp -------------------------------- +30 a cch% +30 mn 00630063006800000000000000000000 +30 mx 006300630068FFFFFFFFFFFFFFFFFFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 00610061006100610061006100610061 +31 mx 00610061006100610061006100610061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 0009 +2 mx FFFF +2 sp -------------------------------- +3 a % +3 mn 00090009000900090009000900090009 +3 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +3 sp -------------------------------- +4 a \_ +4 mn 005F +4 mx 005F +4 sp -------------------------------- +5 a \% +5 mn 0025 +5 mx 0025 +5 sp -------------------------------- +6 a \ +6 mn 005C +6 mx 005C +6 sp -------------------------------- +7 a a +7 mn 0061 +7 mx 0061 +7 sp -------------------------------- +8 a c +8 mn 0063 +8 mx 0063 +8 sp -------------------------------- +9 a a_ +9 mn 00610009 +9 mx 0061FFFF +9 sp -------------------------------- +10 a c_ +10 mn 00630009 +10 mx 0063FFFF +10 sp -------------------------------- +11 a a% +11 mn 00610009000900090009000900090009 +11 mx 0061FFFFFFFFFFFFFFFFFFFFFFFFFFFF +11 sp -------------------------------- +12 a c% +12 mn 00630009000900090009000900090009 +12 mx 0063FFFFFFFFFFFFFFFFFFFFFFFFFFFF +12 sp -------------------------------- +13 a aa +13 mn 00610061 +13 mx 00610061 +13 sp -------------------------------- +14 a cc +14 mn 00630063 +14 mx 00630063 +14 sp -------------------------------- +15 a ch +15 mn 00630068 +15 mx 00630068 +15 sp -------------------------------- +16 a aa_ +16 mn 006100610009 +16 mx 00610061FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 006300630009 +17 mx 00630063FFFF +17 sp -------------------------------- +18 a ch_ +18 mn 006300680009 +18 mx 00630068FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00610061000900090009000900090009 +19 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +19 sp -------------------------------- +20 a cc% +20 mn 00630063000900090009000900090009 +20 mx 00630063FFFFFFFFFFFFFFFFFFFFFFFF +20 sp -------------------------------- +21 a ch% +21 mn 00630068000900090009000900090009 +21 mx 00630068FFFFFFFFFFFFFFFFFFFFFFFF +21 sp -------------------------------- +22 a aaa +22 mn 006100610061 +22 mx 006100610061 +22 sp -------------------------------- +23 a ccc +23 mn 006300630063 +23 mx 006300630063 +23 sp -------------------------------- +24 a cch +24 mn 006300630068 +24 mx 006300630068 +24 sp -------------------------------- +25 a aaa_ +25 mn 0061006100610009 +25 mx 006100610061FFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 0063006300630009 +26 mx 006300630063FFFF +26 sp -------------------------------- +27 a cch_ +27 mn 0063006300680009 +27 mx 006300630068FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00610061006100090009000900090009 +28 mx 006100610061FFFFFFFFFFFFFFFFFFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00630063006300090009000900090009 +29 mx 006300630063FFFFFFFFFFFFFFFFFFFF +29 sp -------------------------------- +30 a cch% +30 mn 00630063006800090009000900090009 +30 mx 006300630068FFFFFFFFFFFFFFFFFFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 00610061006100610061006100610061 +31 mx 00610061006100610061006100610061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET ucs2 COLLATE ucs2_czech_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 0009 +2 mx FFFF +2 sp -------------------------------- +3 a % +3 mn 00090009000900090009000900090009 +3 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +3 sp -------------------------------- +4 a \_ +4 mn 005F +4 mx 005F +4 sp -------------------------------- +5 a \% +5 mn 0025 +5 mx 0025 +5 sp -------------------------------- +6 a \ +6 mn 005C +6 mx 005C +6 sp -------------------------------- +7 a a +7 mn 0061 +7 mx 0061 +7 sp -------------------------------- +8 a c +8 mn 0063 +8 mx 0063 +8 sp -------------------------------- +9 a a_ +9 mn 00610009 +9 mx 0061FFFF +9 sp -------------------------------- +10 a c_ +10 mn 00090009000900090009000900090009 +10 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +10 sp -------------------------------- +11 a a% +11 mn 00610009000900090009000900090009 +11 mx 0061FFFFFFFFFFFFFFFFFFFFFFFFFFFF +11 sp -------------------------------- +12 a c% +12 mn 00090009000900090009000900090009 +12 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +12 sp -------------------------------- +13 a aa +13 mn 00610061 +13 mx 00610061 +13 sp -------------------------------- +14 a cc +14 mn 00630063 +14 mx 00630063 +14 sp -------------------------------- +15 a ch +15 mn 00630068 +15 mx 00630068 +15 sp -------------------------------- +16 a aa_ +16 mn 006100610009 +16 mx 00610061FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 00630009000900090009000900090009 +17 mx 0063FFFFFFFFFFFFFFFFFFFFFFFFFFFF +17 sp -------------------------------- +18 a ch_ +18 mn 006300680009 +18 mx 00630068FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00610061000900090009000900090009 +19 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +19 sp -------------------------------- +20 a cc% +20 mn 00630009000900090009000900090009 +20 mx 0063FFFFFFFFFFFFFFFFFFFFFFFFFFFF +20 sp -------------------------------- +21 a ch% +21 mn 00630068000900090009000900090009 +21 mx 00630068FFFFFFFFFFFFFFFFFFFFFFFF +21 sp -------------------------------- +22 a aaa +22 mn 006100610061 +22 mx 006100610061 +22 sp -------------------------------- +23 a ccc +23 mn 006300630063 +23 mx 006300630063 +23 sp -------------------------------- +24 a cch +24 mn 006300630068 +24 mx 006300630068 +24 sp -------------------------------- +25 a aaa_ +25 mn 0061006100610009 +25 mx 006100610061FFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 00630063000900090009000900090009 +26 mx 00630063FFFFFFFFFFFFFFFFFFFFFFFF +26 sp -------------------------------- +27 a cch_ +27 mn 0063006300680009 +27 mx 006300630068FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00610061006100090009000900090009 +28 mx 006100610061FFFFFFFFFFFFFFFFFFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00630063000900090009000900090009 +29 mx 00630063FFFFFFFFFFFFFFFFFFFFFFFF +29 sp -------------------------------- +30 a cch% +30 mn 00630063006800090009000900090009 +30 mx 006300630068FFFFFFFFFFFFFFFFFFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 00610061006100610061006100610061 +31 mx 00610061006100610061006100610061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET ucs2 COLLATE ucs2_danish_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 0009 +2 mx FFFF +2 sp -------------------------------- +3 a % +3 mn 00090009000900090009000900090009 +3 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +3 sp -------------------------------- +4 a \_ +4 mn 005F +4 mx 005F +4 sp -------------------------------- +5 a \% +5 mn 0025 +5 mx 0025 +5 sp -------------------------------- +6 a \ +6 mn 005C +6 mx 005C +6 sp -------------------------------- +7 a a +7 mn 0061 +7 mx 0061 +7 sp -------------------------------- +8 a c +8 mn 0063 +8 mx 0063 +8 sp -------------------------------- +9 a a_ +9 mn 00090009000900090009000900090009 +9 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9 sp -------------------------------- +10 a c_ +10 mn 00630009 +10 mx 0063FFFF +10 sp -------------------------------- +11 a a% +11 mn 00090009000900090009000900090009 +11 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +11 sp -------------------------------- +12 a c% +12 mn 00630009000900090009000900090009 +12 mx 0063FFFFFFFFFFFFFFFFFFFFFFFFFFFF +12 sp -------------------------------- +13 a aa +13 mn 00610061 +13 mx 00610061 +13 sp -------------------------------- +14 a cc +14 mn 00630063 +14 mx 00630063 +14 sp -------------------------------- +15 a ch +15 mn 00630068 +15 mx 00630068 +15 sp -------------------------------- +16 a aa_ +16 mn 006100610009 +16 mx 00610061FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 006300630009 +17 mx 00630063FFFF +17 sp -------------------------------- +18 a ch_ +18 mn 006300680009 +18 mx 00630068FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00610061000900090009000900090009 +19 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +19 sp -------------------------------- +20 a cc% +20 mn 00630063000900090009000900090009 +20 mx 00630063FFFFFFFFFFFFFFFFFFFFFFFF +20 sp -------------------------------- +21 a ch% +21 mn 00630068000900090009000900090009 +21 mx 00630068FFFFFFFFFFFFFFFFFFFFFFFF +21 sp -------------------------------- +22 a aaa +22 mn 006100610061 +22 mx 006100610061 +22 sp -------------------------------- +23 a ccc +23 mn 006300630063 +23 mx 006300630063 +23 sp -------------------------------- +24 a cch +24 mn 006300630068 +24 mx 006300630068 +24 sp -------------------------------- +25 a aaa_ +25 mn 00610061000900090009000900090009 +25 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 0063006300630009 +26 mx 006300630063FFFF +26 sp -------------------------------- +27 a cch_ +27 mn 0063006300680009 +27 mx 006300630068FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00610061000900090009000900090009 +28 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00630063006300090009000900090009 +29 mx 006300630063FFFFFFFFFFFFFFFFFFFF +29 sp -------------------------------- +30 a cch% +30 mn 00630063006800090009000900090009 +30 mx 006300630068FFFFFFFFFFFFFFFFFFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 00610061006100610061006100610061 +31 mx 00610061006100610061006100610061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf16; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 0000 +2 mx FFFF +2 sp -------------------------------- +3 a % +3 mn 00000000000000000000000000000000 +3 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +3 sp -------------------------------- +4 a \_ +4 mn 005F +4 mx 005F +4 sp -------------------------------- +5 a \% +5 mn 0025 +5 mx 0025 +5 sp -------------------------------- +6 a \ +6 mn 005C +6 mx 005C +6 sp -------------------------------- +7 a a +7 mn 0061 +7 mx 0061 +7 sp -------------------------------- +8 a c +8 mn 0063 +8 mx 0063 +8 sp -------------------------------- +9 a a_ +9 mn 00610000 +9 mx 0061FFFF +9 sp -------------------------------- +10 a c_ +10 mn 00630000 +10 mx 0063FFFF +10 sp -------------------------------- +11 a a% +11 mn 00610000000000000000000000000000 +11 mx 0061FFFFFFFFFFFFFFFFFFFFFFFFFFFF +11 sp -------------------------------- +12 a c% +12 mn 00630000000000000000000000000000 +12 mx 0063FFFFFFFFFFFFFFFFFFFFFFFFFFFF +12 sp -------------------------------- +13 a aa +13 mn 00610061 +13 mx 00610061 +13 sp -------------------------------- +14 a cc +14 mn 00630063 +14 mx 00630063 +14 sp -------------------------------- +15 a ch +15 mn 00630068 +15 mx 00630068 +15 sp -------------------------------- +16 a aa_ +16 mn 006100610000 +16 mx 00610061FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 006300630000 +17 mx 00630063FFFF +17 sp -------------------------------- +18 a ch_ +18 mn 006300680000 +18 mx 00630068FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00610061000000000000000000000000 +19 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +19 sp -------------------------------- +20 a cc% +20 mn 00630063000000000000000000000000 +20 mx 00630063FFFFFFFFFFFFFFFFFFFFFFFF +20 sp -------------------------------- +21 a ch% +21 mn 00630068000000000000000000000000 +21 mx 00630068FFFFFFFFFFFFFFFFFFFFFFFF +21 sp -------------------------------- +22 a aaa +22 mn 006100610061 +22 mx 006100610061 +22 sp -------------------------------- +23 a ccc +23 mn 006300630063 +23 mx 006300630063 +23 sp -------------------------------- +24 a cch +24 mn 006300630068 +24 mx 006300630068 +24 sp -------------------------------- +25 a aaa_ +25 mn 0061006100610000 +25 mx 006100610061FFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 0063006300630000 +26 mx 006300630063FFFF +26 sp -------------------------------- +27 a cch_ +27 mn 0063006300680000 +27 mx 006300630068FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00610061006100000000000000000000 +28 mx 006100610061FFFFFFFFFFFFFFFFFFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00630063006300000000000000000000 +29 mx 006300630063FFFFFFFFFFFFFFFFFFFF +29 sp -------------------------------- +30 a cch% +30 mn 00630063006800000000000000000000 +30 mx 006300630068FFFFFFFFFFFFFFFFFFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 0061006100610061 +31 mx 0061006100610061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf16 COLLATE utf16_unicode_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 0009 +2 mx FFFF +2 sp -------------------------------- +3 a % +3 mn 00090009000900090009000900090009 +3 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +3 sp -------------------------------- +4 a \_ +4 mn 005F +4 mx 005F +4 sp -------------------------------- +5 a \% +5 mn 0025 +5 mx 0025 +5 sp -------------------------------- +6 a \ +6 mn 005C +6 mx 005C +6 sp -------------------------------- +7 a a +7 mn 0061 +7 mx 0061 +7 sp -------------------------------- +8 a c +8 mn 0063 +8 mx 0063 +8 sp -------------------------------- +9 a a_ +9 mn 00610009 +9 mx 0061FFFF +9 sp -------------------------------- +10 a c_ +10 mn 00630009 +10 mx 0063FFFF +10 sp -------------------------------- +11 a a% +11 mn 00610009000900090009000900090009 +11 mx 0061FFFFFFFFFFFFFFFFFFFFFFFFFFFF +11 sp -------------------------------- +12 a c% +12 mn 00630009000900090009000900090009 +12 mx 0063FFFFFFFFFFFFFFFFFFFFFFFFFFFF +12 sp -------------------------------- +13 a aa +13 mn 00610061 +13 mx 00610061 +13 sp -------------------------------- +14 a cc +14 mn 00630063 +14 mx 00630063 +14 sp -------------------------------- +15 a ch +15 mn 00630068 +15 mx 00630068 +15 sp -------------------------------- +16 a aa_ +16 mn 006100610009 +16 mx 00610061FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 006300630009 +17 mx 00630063FFFF +17 sp -------------------------------- +18 a ch_ +18 mn 006300680009 +18 mx 00630068FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00610061000900090009000900090009 +19 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +19 sp -------------------------------- +20 a cc% +20 mn 00630063000900090009000900090009 +20 mx 00630063FFFFFFFFFFFFFFFFFFFFFFFF +20 sp -------------------------------- +21 a ch% +21 mn 00630068000900090009000900090009 +21 mx 00630068FFFFFFFFFFFFFFFFFFFFFFFF +21 sp -------------------------------- +22 a aaa +22 mn 006100610061 +22 mx 006100610061 +22 sp -------------------------------- +23 a ccc +23 mn 006300630063 +23 mx 006300630063 +23 sp -------------------------------- +24 a cch +24 mn 006300630068 +24 mx 006300630068 +24 sp -------------------------------- +25 a aaa_ +25 mn 0061006100610009 +25 mx 006100610061FFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 0063006300630009 +26 mx 006300630063FFFF +26 sp -------------------------------- +27 a cch_ +27 mn 0063006300680009 +27 mx 006300630068FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00610061006100090009000900090009 +28 mx 006100610061FFFFFFFFFFFFFFFFFFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00630063006300090009000900090009 +29 mx 006300630063FFFFFFFFFFFFFFFFFFFF +29 sp -------------------------------- +30 a cch% +30 mn 00630063006800090009000900090009 +30 mx 006300630068FFFFFFFFFFFFFFFFFFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 0061006100610061 +31 mx 0061006100610061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf16 COLLATE utf16_czech_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 0009 +2 mx FFFF +2 sp -------------------------------- +3 a % +3 mn 00090009000900090009000900090009 +3 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +3 sp -------------------------------- +4 a \_ +4 mn 005F +4 mx 005F +4 sp -------------------------------- +5 a \% +5 mn 0025 +5 mx 0025 +5 sp -------------------------------- +6 a \ +6 mn 005C +6 mx 005C +6 sp -------------------------------- +7 a a +7 mn 0061 +7 mx 0061 +7 sp -------------------------------- +8 a c +8 mn 0063 +8 mx 0063 +8 sp -------------------------------- +9 a a_ +9 mn 00610009 +9 mx 0061FFFF +9 sp -------------------------------- +10 a c_ +10 mn 00090009000900090009000900090009 +10 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +10 sp -------------------------------- +11 a a% +11 mn 00610009000900090009000900090009 +11 mx 0061FFFFFFFFFFFFFFFFFFFFFFFFFFFF +11 sp -------------------------------- +12 a c% +12 mn 00090009000900090009000900090009 +12 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +12 sp -------------------------------- +13 a aa +13 mn 00610061 +13 mx 00610061 +13 sp -------------------------------- +14 a cc +14 mn 00630063 +14 mx 00630063 +14 sp -------------------------------- +15 a ch +15 mn 00630068 +15 mx 00630068 +15 sp -------------------------------- +16 a aa_ +16 mn 006100610009 +16 mx 00610061FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 00630009000900090009000900090009 +17 mx 0063FFFFFFFFFFFFFFFFFFFFFFFFFFFF +17 sp -------------------------------- +18 a ch_ +18 mn 006300680009 +18 mx 00630068FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00610061000900090009000900090009 +19 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +19 sp -------------------------------- +20 a cc% +20 mn 00630009000900090009000900090009 +20 mx 0063FFFFFFFFFFFFFFFFFFFFFFFFFFFF +20 sp -------------------------------- +21 a ch% +21 mn 00630068000900090009000900090009 +21 mx 00630068FFFFFFFFFFFFFFFFFFFFFFFF +21 sp -------------------------------- +22 a aaa +22 mn 006100610061 +22 mx 006100610061 +22 sp -------------------------------- +23 a ccc +23 mn 006300630063 +23 mx 006300630063 +23 sp -------------------------------- +24 a cch +24 mn 006300630068 +24 mx 006300630068 +24 sp -------------------------------- +25 a aaa_ +25 mn 0061006100610009 +25 mx 006100610061FFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 00630063000900090009000900090009 +26 mx 00630063FFFFFFFFFFFFFFFFFFFFFFFF +26 sp -------------------------------- +27 a cch_ +27 mn 0063006300680009 +27 mx 006300630068FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00610061006100090009000900090009 +28 mx 006100610061FFFFFFFFFFFFFFFFFFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00630063000900090009000900090009 +29 mx 00630063FFFFFFFFFFFFFFFFFFFFFFFF +29 sp -------------------------------- +30 a cch% +30 mn 00630063006800090009000900090009 +30 mx 006300630068FFFFFFFFFFFFFFFFFFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 0061006100610061 +31 mx 0061006100610061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf16 COLLATE utf16_danish_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 0009 +2 mx FFFF +2 sp -------------------------------- +3 a % +3 mn 00090009000900090009000900090009 +3 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +3 sp -------------------------------- +4 a \_ +4 mn 005F +4 mx 005F +4 sp -------------------------------- +5 a \% +5 mn 0025 +5 mx 0025 +5 sp -------------------------------- +6 a \ +6 mn 005C +6 mx 005C +6 sp -------------------------------- +7 a a +7 mn 0061 +7 mx 0061 +7 sp -------------------------------- +8 a c +8 mn 0063 +8 mx 0063 +8 sp -------------------------------- +9 a a_ +9 mn 00090009000900090009000900090009 +9 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9 sp -------------------------------- +10 a c_ +10 mn 00630009 +10 mx 0063FFFF +10 sp -------------------------------- +11 a a% +11 mn 00090009000900090009000900090009 +11 mx FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +11 sp -------------------------------- +12 a c% +12 mn 00630009000900090009000900090009 +12 mx 0063FFFFFFFFFFFFFFFFFFFFFFFFFFFF +12 sp -------------------------------- +13 a aa +13 mn 00610061 +13 mx 00610061 +13 sp -------------------------------- +14 a cc +14 mn 00630063 +14 mx 00630063 +14 sp -------------------------------- +15 a ch +15 mn 00630068 +15 mx 00630068 +15 sp -------------------------------- +16 a aa_ +16 mn 006100610009 +16 mx 00610061FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 006300630009 +17 mx 00630063FFFF +17 sp -------------------------------- +18 a ch_ +18 mn 006300680009 +18 mx 00630068FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00610061000900090009000900090009 +19 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +19 sp -------------------------------- +20 a cc% +20 mn 00630063000900090009000900090009 +20 mx 00630063FFFFFFFFFFFFFFFFFFFFFFFF +20 sp -------------------------------- +21 a ch% +21 mn 00630068000900090009000900090009 +21 mx 00630068FFFFFFFFFFFFFFFFFFFFFFFF +21 sp -------------------------------- +22 a aaa +22 mn 006100610061 +22 mx 006100610061 +22 sp -------------------------------- +23 a ccc +23 mn 006300630063 +23 mx 006300630063 +23 sp -------------------------------- +24 a cch +24 mn 006300630068 +24 mx 006300630068 +24 sp -------------------------------- +25 a aaa_ +25 mn 00610061000900090009000900090009 +25 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 0063006300630009 +26 mx 006300630063FFFF +26 sp -------------------------------- +27 a cch_ +27 mn 0063006300680009 +27 mx 006300630068FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00610061000900090009000900090009 +28 mx 00610061FFFFFFFFFFFFFFFFFFFFFFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00630063006300090009000900090009 +29 mx 006300630063FFFFFFFFFFFFFFFFFFFF +29 sp -------------------------------- +30 a cch% +30 mn 00630063006800090009000900090009 +30 mx 006300630068FFFFFFFFFFFFFFFFFFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 0061006100610061 +31 mx 0061006100610061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf32; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 00000000 +2 mx 0000FFFF +2 sp -------------------------------- +3 a % +3 mn 00000000000000000000000000000000 +3 mx 0000FFFF0000FFFF0000FFFF0000FFFF +3 sp -------------------------------- +4 a \_ +4 mn 0000005F +4 mx 0000005F +4 sp -------------------------------- +5 a \% +5 mn 00000025 +5 mx 00000025 +5 sp -------------------------------- +6 a \ +6 mn 0000005C +6 mx 0000005C +6 sp -------------------------------- +7 a a +7 mn 00000061 +7 mx 00000061 +7 sp -------------------------------- +8 a c +8 mn 00000063 +8 mx 00000063 +8 sp -------------------------------- +9 a a_ +9 mn 0000006100000000 +9 mx 000000610000FFFF +9 sp -------------------------------- +10 a c_ +10 mn 0000006300000000 +10 mx 000000630000FFFF +10 sp -------------------------------- +11 a a% +11 mn 00000061000000000000000000000000 +11 mx 000000610000FFFF0000FFFF0000FFFF +11 sp -------------------------------- +12 a c% +12 mn 00000063000000000000000000000000 +12 mx 000000630000FFFF0000FFFF0000FFFF +12 sp -------------------------------- +13 a aa +13 mn 0000006100000061 +13 mx 0000006100000061 +13 sp -------------------------------- +14 a cc +14 mn 0000006300000063 +14 mx 0000006300000063 +14 sp -------------------------------- +15 a ch +15 mn 0000006300000068 +15 mx 0000006300000068 +15 sp -------------------------------- +16 a aa_ +16 mn 000000610000006100000000 +16 mx 00000061000000610000FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 000000630000006300000000 +17 mx 00000063000000630000FFFF +17 sp -------------------------------- +18 a ch_ +18 mn 000000630000006800000000 +18 mx 00000063000000680000FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00000061000000610000000000000000 +19 mx 00000061000000610000FFFF0000FFFF +19 sp -------------------------------- +20 a cc% +20 mn 00000063000000630000000000000000 +20 mx 00000063000000630000FFFF0000FFFF +20 sp -------------------------------- +21 a ch% +21 mn 00000063000000680000000000000000 +21 mx 00000063000000680000FFFF0000FFFF +21 sp -------------------------------- +22 a aaa +22 mn 000000610000006100000061 +22 mx 000000610000006100000061 +22 sp -------------------------------- +23 a ccc +23 mn 000000630000006300000063 +23 mx 000000630000006300000063 +23 sp -------------------------------- +24 a cch +24 mn 000000630000006300000068 +24 mx 000000630000006300000068 +24 sp -------------------------------- +25 a aaa_ +25 mn 00000061000000610000006100000000 +25 mx 0000006100000061000000610000FFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 00000063000000630000006300000000 +26 mx 0000006300000063000000630000FFFF +26 sp -------------------------------- +27 a cch_ +27 mn 00000063000000630000006800000000 +27 mx 0000006300000063000000680000FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00000061000000610000006100000000 +28 mx 0000006100000061000000610000FFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00000063000000630000006300000000 +29 mx 0000006300000063000000630000FFFF +29 sp -------------------------------- +30 a cch% +30 mn 00000063000000630000006800000000 +30 mx 0000006300000063000000680000FFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 00000061000000610000006100000061 +31 mx 00000061000000610000006100000061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf32 COLLATE utf32_unicode_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 00000009 +2 mx 0000FFFF +2 sp -------------------------------- +3 a % +3 mn 00000009000000090000000900000009 +3 mx 0000FFFF0000FFFF0000FFFF0000FFFF +3 sp -------------------------------- +4 a \_ +4 mn 0000005F +4 mx 0000005F +4 sp -------------------------------- +5 a \% +5 mn 00000025 +5 mx 00000025 +5 sp -------------------------------- +6 a \ +6 mn 0000005C +6 mx 0000005C +6 sp -------------------------------- +7 a a +7 mn 00000061 +7 mx 00000061 +7 sp -------------------------------- +8 a c +8 mn 00000063 +8 mx 00000063 +8 sp -------------------------------- +9 a a_ +9 mn 0000006100000009 +9 mx 000000610000FFFF +9 sp -------------------------------- +10 a c_ +10 mn 0000006300000009 +10 mx 000000630000FFFF +10 sp -------------------------------- +11 a a% +11 mn 00000061000000090000000900000009 +11 mx 000000610000FFFF0000FFFF0000FFFF +11 sp -------------------------------- +12 a c% +12 mn 00000063000000090000000900000009 +12 mx 000000630000FFFF0000FFFF0000FFFF +12 sp -------------------------------- +13 a aa +13 mn 0000006100000061 +13 mx 0000006100000061 +13 sp -------------------------------- +14 a cc +14 mn 0000006300000063 +14 mx 0000006300000063 +14 sp -------------------------------- +15 a ch +15 mn 0000006300000068 +15 mx 0000006300000068 +15 sp -------------------------------- +16 a aa_ +16 mn 000000610000006100000009 +16 mx 00000061000000610000FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 000000630000006300000009 +17 mx 00000063000000630000FFFF +17 sp -------------------------------- +18 a ch_ +18 mn 000000630000006800000009 +18 mx 00000063000000680000FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00000061000000610000000900000009 +19 mx 00000061000000610000FFFF0000FFFF +19 sp -------------------------------- +20 a cc% +20 mn 00000063000000630000000900000009 +20 mx 00000063000000630000FFFF0000FFFF +20 sp -------------------------------- +21 a ch% +21 mn 00000063000000680000000900000009 +21 mx 00000063000000680000FFFF0000FFFF +21 sp -------------------------------- +22 a aaa +22 mn 000000610000006100000061 +22 mx 000000610000006100000061 +22 sp -------------------------------- +23 a ccc +23 mn 000000630000006300000063 +23 mx 000000630000006300000063 +23 sp -------------------------------- +24 a cch +24 mn 000000630000006300000068 +24 mx 000000630000006300000068 +24 sp -------------------------------- +25 a aaa_ +25 mn 00000061000000610000006100000009 +25 mx 0000006100000061000000610000FFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 00000063000000630000006300000009 +26 mx 0000006300000063000000630000FFFF +26 sp -------------------------------- +27 a cch_ +27 mn 00000063000000630000006800000009 +27 mx 0000006300000063000000680000FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00000061000000610000006100000009 +28 mx 0000006100000061000000610000FFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00000063000000630000006300000009 +29 mx 0000006300000063000000630000FFFF +29 sp -------------------------------- +30 a cch% +30 mn 00000063000000630000006800000009 +30 mx 0000006300000063000000680000FFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 00000061000000610000006100000061 +31 mx 00000061000000610000006100000061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf32 COLLATE utf32_czech_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 00000009 +2 mx 0000FFFF +2 sp -------------------------------- +3 a % +3 mn 00000009000000090000000900000009 +3 mx 0000FFFF0000FFFF0000FFFF0000FFFF +3 sp -------------------------------- +4 a \_ +4 mn 0000005F +4 mx 0000005F +4 sp -------------------------------- +5 a \% +5 mn 00000025 +5 mx 00000025 +5 sp -------------------------------- +6 a \ +6 mn 0000005C +6 mx 0000005C +6 sp -------------------------------- +7 a a +7 mn 00000061 +7 mx 00000061 +7 sp -------------------------------- +8 a c +8 mn 00000063 +8 mx 00000063 +8 sp -------------------------------- +9 a a_ +9 mn 0000006100000009 +9 mx 000000610000FFFF +9 sp -------------------------------- +10 a c_ +10 mn 00000009000000090000000900000009 +10 mx 0000FFFF0000FFFF0000FFFF0000FFFF +10 sp -------------------------------- +11 a a% +11 mn 00000061000000090000000900000009 +11 mx 000000610000FFFF0000FFFF0000FFFF +11 sp -------------------------------- +12 a c% +12 mn 00000009000000090000000900000009 +12 mx 0000FFFF0000FFFF0000FFFF0000FFFF +12 sp -------------------------------- +13 a aa +13 mn 0000006100000061 +13 mx 0000006100000061 +13 sp -------------------------------- +14 a cc +14 mn 0000006300000063 +14 mx 0000006300000063 +14 sp -------------------------------- +15 a ch +15 mn 0000006300000068 +15 mx 0000006300000068 +15 sp -------------------------------- +16 a aa_ +16 mn 000000610000006100000009 +16 mx 00000061000000610000FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 00000063000000090000000900000009 +17 mx 000000630000FFFF0000FFFF0000FFFF +17 sp -------------------------------- +18 a ch_ +18 mn 000000630000006800000009 +18 mx 00000063000000680000FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00000061000000610000000900000009 +19 mx 00000061000000610000FFFF0000FFFF +19 sp -------------------------------- +20 a cc% +20 mn 00000063000000090000000900000009 +20 mx 000000630000FFFF0000FFFF0000FFFF +20 sp -------------------------------- +21 a ch% +21 mn 00000063000000680000000900000009 +21 mx 00000063000000680000FFFF0000FFFF +21 sp -------------------------------- +22 a aaa +22 mn 000000610000006100000061 +22 mx 000000610000006100000061 +22 sp -------------------------------- +23 a ccc +23 mn 000000630000006300000063 +23 mx 000000630000006300000063 +23 sp -------------------------------- +24 a cch +24 mn 000000630000006300000068 +24 mx 000000630000006300000068 +24 sp -------------------------------- +25 a aaa_ +25 mn 00000061000000610000006100000009 +25 mx 0000006100000061000000610000FFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 00000063000000630000000900000009 +26 mx 00000063000000630000FFFF0000FFFF +26 sp -------------------------------- +27 a cch_ +27 mn 00000063000000630000006800000009 +27 mx 0000006300000063000000680000FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00000061000000610000006100000009 +28 mx 0000006100000061000000610000FFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00000063000000630000000900000009 +29 mx 00000063000000630000FFFF0000FFFF +29 sp -------------------------------- +30 a cch% +30 mn 00000063000000630000006800000009 +30 mx 0000006300000063000000680000FFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 00000061000000610000006100000061 +31 mx 00000061000000610000006100000061 +31 sp -------------------------------- +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf32 COLLATE utf32_danish_ci; +SELECT * FROM v1; +id name val +1 a +1 mn +1 mx +1 sp -------------------------------- +2 a _ +2 mn 00000009 +2 mx 0000FFFF +2 sp -------------------------------- +3 a % +3 mn 00000009000000090000000900000009 +3 mx 0000FFFF0000FFFF0000FFFF0000FFFF +3 sp -------------------------------- +4 a \_ +4 mn 0000005F +4 mx 0000005F +4 sp -------------------------------- +5 a \% +5 mn 00000025 +5 mx 00000025 +5 sp -------------------------------- +6 a \ +6 mn 0000005C +6 mx 0000005C +6 sp -------------------------------- +7 a a +7 mn 00000061 +7 mx 00000061 +7 sp -------------------------------- +8 a c +8 mn 00000063 +8 mx 00000063 +8 sp -------------------------------- +9 a a_ +9 mn 00000009000000090000000900000009 +9 mx 0000FFFF0000FFFF0000FFFF0000FFFF +9 sp -------------------------------- +10 a c_ +10 mn 0000006300000009 +10 mx 000000630000FFFF +10 sp -------------------------------- +11 a a% +11 mn 00000009000000090000000900000009 +11 mx 0000FFFF0000FFFF0000FFFF0000FFFF +11 sp -------------------------------- +12 a c% +12 mn 00000063000000090000000900000009 +12 mx 000000630000FFFF0000FFFF0000FFFF +12 sp -------------------------------- +13 a aa +13 mn 0000006100000061 +13 mx 0000006100000061 +13 sp -------------------------------- +14 a cc +14 mn 0000006300000063 +14 mx 0000006300000063 +14 sp -------------------------------- +15 a ch +15 mn 0000006300000068 +15 mx 0000006300000068 +15 sp -------------------------------- +16 a aa_ +16 mn 000000610000006100000009 +16 mx 00000061000000610000FFFF +16 sp -------------------------------- +17 a cc_ +17 mn 000000630000006300000009 +17 mx 00000063000000630000FFFF +17 sp -------------------------------- +18 a ch_ +18 mn 000000630000006800000009 +18 mx 00000063000000680000FFFF +18 sp -------------------------------- +19 a aa% +19 mn 00000061000000610000000900000009 +19 mx 00000061000000610000FFFF0000FFFF +19 sp -------------------------------- +20 a cc% +20 mn 00000063000000630000000900000009 +20 mx 00000063000000630000FFFF0000FFFF +20 sp -------------------------------- +21 a ch% +21 mn 00000063000000680000000900000009 +21 mx 00000063000000680000FFFF0000FFFF +21 sp -------------------------------- +22 a aaa +22 mn 000000610000006100000061 +22 mx 000000610000006100000061 +22 sp -------------------------------- +23 a ccc +23 mn 000000630000006300000063 +23 mx 000000630000006300000063 +23 sp -------------------------------- +24 a cch +24 mn 000000630000006300000068 +24 mx 000000630000006300000068 +24 sp -------------------------------- +25 a aaa_ +25 mn 00000061000000610000000900000009 +25 mx 00000061000000610000FFFF0000FFFF +25 sp -------------------------------- +26 a ccc_ +26 mn 00000063000000630000006300000009 +26 mx 0000006300000063000000630000FFFF +26 sp -------------------------------- +27 a cch_ +27 mn 00000063000000630000006800000009 +27 mx 0000006300000063000000680000FFFF +27 sp -------------------------------- +28 a aaa% +28 mn 00000061000000610000000900000009 +28 mx 00000061000000610000FFFF0000FFFF +28 sp -------------------------------- +29 a ccc% +29 mn 00000063000000630000006300000009 +29 mx 0000006300000063000000630000FFFF +29 sp -------------------------------- +30 a cch% +30 mn 00000063000000630000006800000009 +30 mx 0000006300000063000000680000FFFF +30 sp -------------------------------- +31 a aaaaaaaaaaaaaaaaaaaa +31 mn 00000061000000610000006100000061 +31 mx 00000061000000610000006100000061 +31 sp -------------------------------- +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result index 04727f84ff2..7b9023578b3 100644 --- a/mysql-test/r/ctype_uca.result +++ b/mysql-test/r/ctype_uca.result @@ -2888,3 +2888,101 @@ a hex(b) c DROP TABLE t1; set names utf8; End for 5.0 tests +# +# Start of 5.5 tests +# +SET collation_connection=utf8_czech_ci; +SELECT @@collation_connection; +@@collation_connection +utf8_czech_ci +# +# Bug#57737 Character sets: search fails with like, contraction, index +# +CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS s1 LIMIT 0; +INSERT INTO t1 VALUES ('c'),('ce'),('cé'),('ch'); +SELECT * FROM t1 WHERE s1 LIKE 'c%'; +s1 +c +ce +cé +ch +ALTER TABLE t1 ADD KEY s1 (s1); +SELECT * FROM t1 WHERE s1 LIKE 'c%'; +s1 +c +ce +cé +ch +ALTER TABLE t1 DROP KEY s1, ADD KEY(s1(1)); +SELECT * FROM t1 WHERE s1 LIKE 'ch'; +s1 +ch +DROP TABLE t1; +SELECT @@collation_connection; +@@collation_connection +utf8_czech_ci +# +# Bug#57737 Character sets: search fails with like, contraction, index +# Part#2 - ignorable characters +# +CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS s1 LIMIT 0; +INSERT INTO t1 VALUES ('a\0\0\0\0\0\t'),('a'),('b'),('c'),('d'),('e'); +SELECT HEX(s1) FROM t1 WHERE s1 LIKE 'a%'; +HEX(s1) +61000000000009 +61 +ALTER TABLE t1 ADD KEY s1 (s1); +SELECT HEX(s1) FROM t1 WHERE s1 LIKE 'a%'; +HEX(s1) +61000000000009 +61 +DROP TABLE t1; +SET collation_connection=ucs2_czech_ci; +SELECT @@collation_connection; +@@collation_connection +ucs2_czech_ci +# +# Bug#57737 Character sets: search fails with like, contraction, index +# +CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS s1 LIMIT 0; +INSERT INTO t1 VALUES ('c'),('ce'),('cé'),('ch'); +SELECT * FROM t1 WHERE s1 LIKE 'c%'; +s1 +c +ce +cé +ch +ALTER TABLE t1 ADD KEY s1 (s1); +SELECT * FROM t1 WHERE s1 LIKE 'c%'; +s1 +c +ce +cé +ch +ALTER TABLE t1 DROP KEY s1, ADD KEY(s1(1)); +SELECT * FROM t1 WHERE s1 LIKE 'ch'; +s1 +ch +DROP TABLE t1; +SELECT @@collation_connection; +@@collation_connection +ucs2_czech_ci +# +# Bug#57737 Character sets: search fails with like, contraction, index +# Part#2 - ignorable characters +# +CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS s1 LIMIT 0; +INSERT INTO t1 VALUES ('a\0\0\0\0\0\t'),('a'),('b'),('c'),('d'),('e'); +SELECT HEX(s1) FROM t1 WHERE s1 LIKE 'a%'; +HEX(s1) +0061000000000000000000000009 +0061 +ALTER TABLE t1 ADD KEY s1 (s1); +SELECT HEX(s1) FROM t1 WHERE s1 LIKE 'a%'; +HEX(s1) +0061000000000000000000000009 +0061 +DROP TABLE t1; +# +# End of 5.5 tests +# diff --git a/mysql-test/r/ctype_utf16_uca.result b/mysql-test/r/ctype_utf16_uca.result index d83ef2af09e..18adaf2f79c 100644 --- a/mysql-test/r/ctype_utf16_uca.result +++ b/mysql-test/r/ctype_utf16_uca.result @@ -2368,6 +2368,52 @@ NULL NULL NULL drop table t1; +SET collation_connection=utf16_czech_ci; +SELECT @@collation_connection; +@@collation_connection +utf16_czech_ci +# +# Bug#57737 Character sets: search fails with like, contraction, index +# +CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS s1 LIMIT 0; +INSERT INTO t1 VALUES ('c'),('ce'),('cé'),('ch'); +SELECT * FROM t1 WHERE s1 LIKE 'c%'; +s1 +c +ce +cé +ch +ALTER TABLE t1 ADD KEY s1 (s1); +SELECT * FROM t1 WHERE s1 LIKE 'c%'; +s1 +c +ce +cé +ch +ALTER TABLE t1 DROP KEY s1, ADD KEY(s1(1)); +SELECT * FROM t1 WHERE s1 LIKE 'ch'; +s1 +ch +DROP TABLE t1; +SELECT @@collation_connection; +@@collation_connection +utf16_czech_ci +# +# Bug#57737 Character sets: search fails with like, contraction, index +# Part#2 - ignorable characters +# +CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS s1 LIMIT 0; +INSERT INTO t1 VALUES ('a\0\0\0\0\0\t'),('a'),('b'),('c'),('d'),('e'); +SELECT HEX(s1) FROM t1 WHERE s1 LIKE 'a%'; +HEX(s1) +0061000000000000000000000009 +0061 +ALTER TABLE t1 ADD KEY s1 (s1); +SELECT HEX(s1) FROM t1 WHERE s1 LIKE 'a%'; +HEX(s1) +0061000000000000000000000009 +0061 +DROP TABLE t1; # # End of 5.5 tests # diff --git a/mysql-test/r/ctype_utf32_uca.result b/mysql-test/r/ctype_utf32_uca.result index 5006009fc9c..fd5a4199217 100644 --- a/mysql-test/r/ctype_utf32_uca.result +++ b/mysql-test/r/ctype_utf32_uca.result @@ -2368,6 +2368,52 @@ NULL NULL NULL drop table t1; +SET collation_connection=utf32_czech_ci; +SELECT @@collation_connection; +@@collation_connection +utf32_czech_ci +# +# Bug#57737 Character sets: search fails with like, contraction, index +# +CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS s1 LIMIT 0; +INSERT INTO t1 VALUES ('c'),('ce'),('cé'),('ch'); +SELECT * FROM t1 WHERE s1 LIKE 'c%'; +s1 +c +ce +cé +ch +ALTER TABLE t1 ADD KEY s1 (s1); +SELECT * FROM t1 WHERE s1 LIKE 'c%'; +s1 +c +ce +cé +ch +ALTER TABLE t1 DROP KEY s1, ADD KEY(s1(1)); +SELECT * FROM t1 WHERE s1 LIKE 'ch'; +s1 +ch +DROP TABLE t1; +SELECT @@collation_connection; +@@collation_connection +utf32_czech_ci +# +# Bug#57737 Character sets: search fails with like, contraction, index +# Part#2 - ignorable characters +# +CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS s1 LIMIT 0; +INSERT INTO t1 VALUES ('a\0\0\0\0\0\t'),('a'),('b'),('c'),('d'),('e'); +SELECT HEX(s1) FROM t1 WHERE s1 LIKE 'a%'; +HEX(s1) +00000061000000000000000000000000000000000000000000000009 +00000061 +ALTER TABLE t1 ADD KEY s1 (s1); +SELECT HEX(s1) FROM t1 WHERE s1 LIKE 'a%'; +HEX(s1) +00000061000000000000000000000000000000000000000000000009 +00000061 +DROP TABLE t1; # # End of 5.5 tests # diff --git a/mysql-test/t/ctype_like_range.test b/mysql-test/t/ctype_like_range.test new file mode 100644 index 00000000000..34a7637222b --- /dev/null +++ b/mysql-test/t/ctype_like_range.test @@ -0,0 +1,87 @@ +--source include/have_debug.inc +--source include/have_ucs2.inc +--source include/have_utf16.inc +--source include/have_utf32.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +--enable_warnings + +CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, a VARBINARY(32)); +INSERT INTO t1 (a) VALUES (''),('_'),('%'),('\_'),('\%'),('\\'); +INSERT INTO t1 (a) VALUES ('a'),('c'); +INSERT INTO t1 (a) VALUES ('a_'),('c_'); +INSERT INTO t1 (a) VALUES ('a%'),('c%'); +INSERT INTO t1 (a) VALUES ('aa'),('cc'),('ch'); +INSERT INTO t1 (a) VALUES ('aa_'),('cc_'),('ch_'); +INSERT INTO t1 (a) VALUES ('aa%'),('cc%'),('ch%'); +INSERT INTO t1 (a) VALUES ('aaa'),('ccc'),('cch'); +INSERT INTO t1 (a) VALUES ('aaa_'),('ccc_'),('cch_'); +INSERT INTO t1 (a) VALUES ('aaa%'),('ccc%'),('cch%'); +INSERT INTO t1 (a) VALUES ('aaaaaaaaaaaaaaaaaaaa'); + +CREATE VIEW v1 AS + SELECT id, 'a' AS name, a AS val FROM t1 +UNION + SELECT id, 'mn', HEX(LIKE_RANGE_MIN(a, 16)) AS min FROM t1 +UNION + SELECT id, 'mx', HEX(LIKE_RANGE_MAX(a, 16)) AS max FROM t1 +UNION + SELECT id, 'sp', REPEAT('-', 32) AS sep FROM t1 +ORDER BY id, name; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET latin1; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf8; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_czech_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_danish_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET ucs2; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET ucs2 COLLATE ucs2_czech_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET ucs2 COLLATE ucs2_danish_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf16; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf16 COLLATE utf16_unicode_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf16 COLLATE utf16_czech_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf16 COLLATE utf16_danish_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf32; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf32 COLLATE utf32_unicode_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf32 COLLATE utf32_czech_ci; +SELECT * FROM v1; + +ALTER TABLE t1 MODIFY a VARCHAR(32) CHARACTER SET utf32 COLLATE utf32_danish_ci; +SELECT * FROM v1; + +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test index 11a489ba24d..723962bbb3f 100644 --- a/mysql-test/t/ctype_uca.test +++ b/mysql-test/t/ctype_uca.test @@ -545,3 +545,19 @@ set collation_connection=ucs2_unicode_ci; set names utf8; -- echo End for 5.0 tests + +--echo # +--echo # Start of 5.5 tests +--echo # +# +# Test my_like_range and contractions +# +SET collation_connection=utf8_czech_ci; +--source include/ctype_czech.inc +--source include/ctype_like_ignorable.inc +SET collation_connection=ucs2_czech_ci; +--source include/ctype_czech.inc +--source include/ctype_like_ignorable.inc +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/mysql-test/t/ctype_utf16_uca.test b/mysql-test/t/ctype_utf16_uca.test index 5314777c6f4..a6295c82dec 100644 --- a/mysql-test/t/ctype_utf16_uca.test +++ b/mysql-test/t/ctype_utf16_uca.test @@ -284,6 +284,13 @@ DROP TABLE IF EXISTS t1; set collation_connection=utf16_unicode_ci; --source include/ctype_regex.inc +# +# Test my_like_range and contractions +# +SET collation_connection=utf16_czech_ci; +--source include/ctype_czech.inc +--source include/ctype_like_ignorable.inc + --echo # --echo # End of 5.5 tests diff --git a/mysql-test/t/ctype_utf32_uca.test b/mysql-test/t/ctype_utf32_uca.test index 9386cc9e65e..a62ffbf95c7 100644 --- a/mysql-test/t/ctype_utf32_uca.test +++ b/mysql-test/t/ctype_utf32_uca.test @@ -286,6 +286,14 @@ set collation_connection=utf32_unicode_ci; --source include/ctype_regex.inc +# +# Test my_like_range and contractions +# +SET collation_connection=utf32_czech_ci; +--source include/ctype_czech.inc +--source include/ctype_like_ignorable.inc + + --echo # --echo # End of 5.5 tests --echo # diff --git a/sql/item_create.cc b/sql/item_create.cc index 672e59986d5..1ae65926013 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -1330,6 +1330,34 @@ protected: }; +#ifndef DBUG_OFF +class Create_func_like_range_min : public Create_func_arg2 +{ +public: + virtual Item *create(THD *thd, Item *arg1, Item *arg2); + + static Create_func_like_range_min s_singleton; + +protected: + Create_func_like_range_min() {} + virtual ~Create_func_like_range_min() {} +}; + + +class Create_func_like_range_max : public Create_func_arg2 +{ +public: + virtual Item *create(THD *thd, Item *arg1, Item *arg2); + + static Create_func_like_range_max s_singleton; + +protected: + Create_func_like_range_max() {} + virtual ~Create_func_like_range_max() {} +}; +#endif + + class Create_func_ln : public Create_func_arg1 { public: @@ -3836,6 +3864,26 @@ Create_func_length::create(THD *thd, Item *arg1) } +#ifndef DBUG_OFF +Create_func_like_range_min Create_func_like_range_min::s_singleton; + +Item* +Create_func_like_range_min::create(THD *thd, Item *arg1, Item *arg2) +{ + return new (thd->mem_root) Item_func_like_range_min(arg1, arg2); +} + + +Create_func_like_range_max Create_func_like_range_max::s_singleton; + +Item* +Create_func_like_range_max::create(THD *thd, Item *arg1, Item *arg2) +{ + return new (thd->mem_root) Item_func_like_range_max(arg1, arg2); +} +#endif + + Create_func_ln Create_func_ln::s_singleton; Item* @@ -4924,6 +4972,10 @@ static Native_func_registry func_array[] = { { C_STRING_WITH_LEN("LCASE") }, BUILDER(Create_func_lcase)}, { { C_STRING_WITH_LEN("LEAST") }, BUILDER(Create_func_least)}, { { C_STRING_WITH_LEN("LENGTH") }, BUILDER(Create_func_length)}, +#ifndef DBUG_OFF + { { C_STRING_WITH_LEN("LIKE_RANGE_MIN") }, BUILDER(Create_func_like_range_min)}, + { { C_STRING_WITH_LEN("LIKE_RANGE_MAX") }, BUILDER(Create_func_like_range_max)}, +#endif { { C_STRING_WITH_LEN("LINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)}, { { C_STRING_WITH_LEN("LINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)}, { { C_STRING_WITH_LEN("LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)}, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 89c1e785c71..803a5367bc6 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3128,6 +3128,41 @@ String *Item_func_unhex::val_str(String *str) } +#ifndef DBUG_OFF +String *Item_func_like_range::val_str(String *str) +{ + DBUG_ASSERT(fixed == 1); + longlong nbytes= args[1]->val_int(); + String *res= args[0]->val_str(str); + size_t min_len, max_len; + CHARSET_INFO *cs= collation.collation; + + if (!res || args[0]->null_value || args[1]->null_value || + nbytes < 0 || nbytes > MAX_BLOB_WIDTH || + min_str.alloc(nbytes) || max_str.alloc(nbytes)) + goto err; + null_value=0; + + if (cs->coll->like_range(cs, res->ptr(), res->length(), + '\\', '_', '%', nbytes, + (char*) min_str.ptr(), (char*) max_str.ptr(), + &min_len, &max_len)) + goto err; + + min_str.set_charset(collation.collation); + max_str.set_charset(collation.collation); + min_str.length(min_len); + max_str.length(max_len); + + return is_min ? &min_str : &max_str; + +err: + null_value= 1; + return 0; +} +#endif + + void Item_func_binary::print(String *str, enum_query_type query_type) { str->append(STRING_WITH_LEN("cast(")); diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 5dcef2e671f..d76e139883c 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -657,6 +657,46 @@ public: }; +#ifndef DBUG_OFF +class Item_func_like_range :public Item_str_func +{ +protected: + String min_str; + String max_str; + const bool is_min; +public: + Item_func_like_range(Item *a, Item *b, bool is_min_arg) + :Item_str_func(a, b), is_min(is_min_arg) + { maybe_null= 1; } + String *val_str(String *); + void fix_length_and_dec() + { + collation.set(args[0]->collation); + decimals=0; + max_length= MAX_BLOB_WIDTH; + } +}; + + +class Item_func_like_range_min :public Item_func_like_range +{ +public: + Item_func_like_range_min(Item *a, Item *b) + :Item_func_like_range(a, b, true) { } + const char *func_name() const { return "like_range_min"; } +}; + + +class Item_func_like_range_max :public Item_func_like_range +{ +public: + Item_func_like_range_max(Item *a, Item *b) + :Item_func_like_range(a, b, false) { } + const char *func_name() const { return "like_range_max"; } +}; +#endif + + class Item_func_binary :public Item_str_func { public: diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index b2f2e3cd22e..8b985b7405b 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -636,7 +636,7 @@ static void pad_max_char(CHARSET_INFO *cs, char *str, char *end) DBUG_ASSERT(buflen > 0); do { - if ((str + buflen) < end) + if ((str + buflen) <= end) { /* Enough space for the characer */ memcpy(str, buf, buflen); @@ -802,6 +802,192 @@ fill_max_and_min: } +/** + Calculate min_str and max_str that ranges a LIKE string. + Generic function, currently used for ucs2, utf16, utf32, + but should be suitable for any other character sets with + cs->min_sort_char and cs->max_sort_char represented in + Unicode code points. + + @param cs Character set and collation pointer + @param ptr Pointer to LIKE pattern. + @param ptr_length Length of LIKE pattern. + @param escape Escape character pattern, typically '\'. + @param w_one 'One character' pattern, typically '_'. + @param w_many 'Many characters' pattern, typically '%'. + @param res_length Length of min_str and max_str. + + @param[out] min_str Smallest string that ranges LIKE. + @param[out] max_str Largest string that ranges LIKE. + @param[out] min_len Length of min_str + @param[out] max_len Length of max_str + + @return Optimization status. + @retval FALSE if LIKE pattern can be optimized + @rerval TRUE if LIKE can't be optimized. +*/ +my_bool +my_like_range_generic(CHARSET_INFO *cs, + const char *ptr, size_t ptr_length, + pbool escape, pbool w_one, pbool w_many, + size_t res_length, + char *min_str,char *max_str, + size_t *min_length,size_t *max_length) +{ + const char *end= ptr + ptr_length; + const char *min_org= min_str; + const char *max_org= max_str; + char *min_end= min_str + res_length; + char *max_end= max_str + res_length; + size_t charlen= res_length / cs->mbmaxlen; + size_t res_length_diff; + my_bool have_contractions= my_cs_have_contractions(cs); + + for ( ; charlen > 0; charlen--) + { + my_wc_t wc, wc2; + int res; + if ((res= cs->cset->mb_wc(cs, &wc, (uchar*) ptr, (uchar*) end)) <= 0) + { + if (res == MY_CS_ILSEQ) /* Bad sequence */ + return TRUE; /* min_length and max_length are not important */ + break; /* End of the string */ + } + ptr+= res; + + if (wc == (my_wc_t) escape) + { + if ((res= cs->cset->mb_wc(cs, &wc, (uchar*) ptr, (uchar*) end)) <= 0) + { + if (res == MY_CS_ILSEQ) + return TRUE; /* min_length and max_length are not important */ + /* + End of the string: Escape is the last character. + Put escape as a normal character. + We'll will leave the loop on the next iteration. + */ + } + else + ptr+= res; + + /* Put escape character to min_str and max_str */ + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) min_str, (uchar*) min_end)) <= 0) + goto pad_set_lengths; /* No space */ + min_str+= res; + + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) max_str, (uchar*) max_end)) <= 0) + goto pad_set_lengths; /* No space */ + max_str+= res; + continue; + } + else if (wc == (my_wc_t) w_one) + { + if ((res= cs->cset->wc_mb(cs, cs->min_sort_char, + (uchar*) min_str, (uchar*) min_end)) <= 0) + goto pad_set_lengths; + min_str+= res; + + if ((res= cs->cset->wc_mb(cs, cs->max_sort_char, + (uchar*) max_str, (uchar*) max_end)) <= 0) + goto pad_set_lengths; + max_str+= res; + continue; + } + else if (wc == (my_wc_t) w_many) + { + /* + Calculate length of keys: + a\min\min... is the smallest possible string + a\max\max... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? + (size_t) (min_str - min_org) : + res_length); + *max_length= res_length; + goto pad_min_max; + } + + if (have_contractions && + my_cs_can_be_contraction_head(cs, wc) && + (res= cs->cset->mb_wc(cs, &wc2, (uchar*) ptr, (uchar*) end)) > 0) + { + uint16 *weight; + if ((wc2 == (my_wc_t) w_one || wc2 == (my_wc_t) w_many)) + { + /* Contraction head followed by a wildcard */ + *min_length= *max_length= res_length; + goto pad_min_max; + } + + if (my_cs_can_be_contraction_tail(cs, wc2) && + (weight= my_cs_contraction2_weight(cs, wc, wc2)) && weight[0]) + { + /* Contraction found */ + if (charlen == 1) + { + /* contraction does not fit to result */ + *min_length= *max_length= res_length; + goto pad_min_max; + } + + ptr+= res; + charlen--; + + /* Put contraction head */ + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) min_str, (uchar*) min_end)) <= 0) + goto pad_set_lengths; + min_str+= res; + + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) max_str, (uchar*) max_end)) <= 0) + goto pad_set_lengths; + max_str+= res; + wc= wc2; /* Prepare to put contraction tail */ + } + } + + /* Normal character, or contraction tail */ + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) min_str, (uchar*) min_end)) <= 0) + goto pad_set_lengths; + min_str+= res; + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) max_str, (uchar*) max_end)) <= 0) + goto pad_set_lengths; + max_str+= res; + } + +pad_set_lengths: + *min_length= (size_t) (min_str - min_org); + *max_length= (size_t) (max_str - max_org); + +pad_min_max: + /* + Fill up max_str and min_str to res_length. + fill() cannot set incomplete characters and + requires that "length" argument is divisible to mbminlen. + Make sure to call fill() with proper "length" argument. + */ + res_length_diff= res_length % cs->mbminlen; + cs->cset->fill(cs, min_str, min_end - min_str - res_length_diff, + cs->min_sort_char); + cs->cset->fill(cs, max_str, max_end - max_str - res_length_diff, + cs->max_sort_char); + + /* In case of incomplete characters set the remainder to 0x00's */ + if (res_length_diff) + { + /* Example: odd res_length for ucs2 */ + memset(min_end - res_length_diff, 0, res_length_diff); + memset(max_end - res_length_diff, 0, res_length_diff); + } + return FALSE; +} + + int my_wildcmp_mb_bin(CHARSET_INFO *cs, const char *str,const char *str_end, diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 3cf61b213eb..2f7bf030d90 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -8127,7 +8127,7 @@ MY_COLLATION_HANDLER my_collation_ucs2_uca_handler = my_strnncollsp_ucs2_uca, my_strnxfrm_ucs2_uca, my_strnxfrmlen_simple, - my_like_range_ucs2, + my_like_range_generic, my_wildcmp_uca, NULL, my_instr_mb, @@ -10134,7 +10134,7 @@ MY_COLLATION_HANDLER my_collation_utf32_uca_handler = my_strnncollsp_any_uca, my_strnxfrm_any_uca, my_strnxfrmlen_simple, - my_like_range_utf32, + my_like_range_generic, my_wildcmp_uca, NULL, my_instr_mb, @@ -10801,7 +10801,7 @@ MY_COLLATION_HANDLER my_collation_utf16_uca_handler = my_strnncollsp_any_uca, my_strnxfrm_any_uca, my_strnxfrmlen_simple, - my_like_range_utf16, + my_like_range_generic, my_wildcmp_uca, NULL, my_instr_mb, diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 09652c5884e..d9f546d435e 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -903,7 +903,8 @@ static void my_fill_mb2(CHARSET_INFO *cs __attribute__((unused)), char *s, size_t l, int fill) { - for ( ; l >= 2; s[0]= 0, s[1]= fill, s+= 2, l-= 2); + DBUG_ASSERT(fill <= 0xFFFF); + for ( ; l >= 2; s[0]= (fill >> 8), s[1]= (fill & 0xFF), s+= 2, l-= 2); } @@ -1563,98 +1564,6 @@ my_hash_sort_utf16_bin(CHARSET_INFO *cs __attribute__((unused)), } -/** - Calculate min_str and max_str that ranges a LIKE string. - - @param ptr Pointer to LIKE pattern. - @param ptr_length Length of LIKE pattern. - @param escape Escape character in LIKE. (Normally '\'). - All escape characters should be removed - from min_str and max_str. - @param res_length Length of min_str and max_str. - @param min_str Smallest case sensitive string that ranges LIKE. - Should be space padded to res_length. - @param max_str Largest case sensitive string that ranges LIKE. - Normally padded with the biggest character sort value. - - @return Optimization status. - @retval FALSE if LIKE pattern can be optimized - @rerval TRUE if LIKE can't be optimized. -*/ - -my_bool -my_like_range_utf16(CHARSET_INFO *cs, - const char *ptr, size_t ptr_length, - pbool escape, pbool w_one, pbool w_many, - size_t res_length, - char *min_str,char *max_str, - size_t *min_length,size_t *max_length) -{ - const char *end=ptr+ptr_length; - char *min_org=min_str; - char *min_end=min_str+res_length; - size_t charlen= res_length / cs->mbmaxlen; - - for ( ; ptr + 1 < end && min_str + 1 < min_end && charlen > 0 - ; ptr+=2, charlen--) - { - if (ptr[0] == '\0' && ptr[1] == escape && ptr + 1 < end) - { - ptr+=2; /* Skip escape */ - *min_str++= *max_str++ = ptr[0]; - *min_str++= *max_str++ = ptr[1]; - continue; - } - if (ptr[0] == '\0' && ptr[1] == w_one) /* '_' in SQL */ - { - *min_str++= (char) (cs->min_sort_char >> 8); - *min_str++= (char) (cs->min_sort_char & 255); - *max_str++= (char) (cs->max_sort_char >> 8); - *max_str++= (char) (cs->max_sort_char & 255); - continue; - } - if (ptr[0] == '\0' && ptr[1] == w_many) /* '%' in SQL */ - { - /* - Calculate length of keys: - 'a\0\0... is the smallest possible string when we have space expand - a\ff\ff... is the biggest possible string - */ - *min_length= ((cs->state & MY_CS_BINSORT) ? (size_t) (min_str - min_org) : - res_length); - *max_length= res_length; - do { - *min_str++ = 0; - *min_str++ = 0; - *max_str++ = (char) (cs->max_sort_char >> 8); - *max_str++ = (char) (cs->max_sort_char & 255); - } while (min_str + 1 < min_end); - return FALSE; - } - *min_str++= *max_str++ = ptr[0]; - *min_str++= *max_str++ = ptr[1]; - } - - /* Temporary fix for handling w_one at end of string (key compression) */ - { - char *tmp; - for (tmp= min_str ; tmp-1 > min_org && tmp[-1] == '\0' && tmp[-2]=='\0';) - { - *--tmp=' '; - *--tmp='\0'; - } - } - - *min_length= *max_length = (size_t) (min_str - min_org); - while (min_str + 1 < min_end) - { - *min_str++ = *max_str++ = '\0'; - *min_str++ = *max_str++ = ' '; /* Because if key compression */ - } - return FALSE; -} - - static MY_COLLATION_HANDLER my_collation_utf16_general_ci_handler = { NULL, /* init */ @@ -1662,7 +1571,7 @@ static MY_COLLATION_HANDLER my_collation_utf16_general_ci_handler = my_strnncollsp_utf16, my_strnxfrm_unicode, my_strnxfrmlen_simple, - my_like_range_utf16, + my_like_range_generic, my_wildcmp_utf16_ci, my_strcasecmp_mb2_or_mb4, my_instr_mb, @@ -1678,7 +1587,7 @@ static MY_COLLATION_HANDLER my_collation_utf16_bin_handler = my_strnncollsp_utf16_bin, my_strnxfrm_unicode_full_bin, my_strnxfrmlen_unicode_full_bin, - my_like_range_utf16, + my_like_range_generic, my_wildcmp_utf16_bin, my_strcasecmp_mb2_or_mb4, my_instr_mb, @@ -2551,113 +2460,6 @@ my_strnncollsp_utf32_bin(CHARSET_INFO *cs __attribute__((unused)), } -/** - Calculate min_str and max_str that ranges a LIKE string. - - @param ptr Pointer to LIKE pattern. - @param ptr_length Length of LIKE pattern. - @param escape Escape character in LIKE. (Normally '\'). - All escape characters should be removed - from min_str and max_str. - @param res_length Length of min_str and max_str. - @param min_str Smallest case sensitive string that ranges LIKE. - Should be space padded to res_length. - @param max_str Largest case sensitive string that ranges LIKE. - Normally padded with the biggest character sort value. - - @return Optimization status. - @retval FALSE if LIKE pattern can be optimized - @rerval TRUE if LIKE can't be optimized. -*/ - -my_bool -my_like_range_utf32(CHARSET_INFO *cs, - const char *ptr, size_t ptr_length, - pbool escape, pbool w_one, pbool w_many, - size_t res_length, - char *min_str,char *max_str, - size_t *min_length,size_t *max_length) -{ - const char *end= ptr + ptr_length; - char *min_org= min_str; - char *min_end= min_str + res_length; - char *max_end= max_str + res_length; - size_t charlen= res_length / cs->mbmaxlen; - - DBUG_ASSERT((res_length % 4) == 0); - - for ( ; charlen > 0; ptr+= 4, charlen--) - { - my_wc_t wc; - int res; - if ((res= my_utf32_uni(cs, &wc, (uchar*) ptr, (uchar*) end)) < 0) - { - my_fill_utf32(cs, min_str, min_end - min_str, cs->min_sort_char); - my_fill_utf32(cs, max_str, min_end - min_str, cs->max_sort_char); - /* min_length and max_legnth are not important */ - return TRUE; - } - - if (wc == (my_wc_t) escape) - { - ptr+= 4; /* Skip escape */ - if ((res= my_utf32_uni(cs, &wc, (uchar*) ptr, (uchar*) end)) < 0) - { - my_fill_utf32(cs, min_str, min_end - min_str, cs->min_sort_char); - my_fill_utf32(cs, max_str, max_end - min_str, cs->max_sort_char); - /* min_length and max_length are not important */ - return TRUE; - } - if (my_uni_utf32(cs, wc, (uchar*) min_str, (uchar*) min_end) != 4 || - my_uni_utf32(cs, wc, (uchar*) max_str, (uchar*) max_end) != 4) - goto pad_set_lengths; - *min_str++= 4; - *max_str++= 4; - continue; - } - - if (wc == (my_wc_t) w_one) - { - if (my_uni_utf32(cs, cs->min_sort_char, (uchar*) min_str, (uchar*) min_end) != 4 || - my_uni_utf32(cs, cs->max_sort_char, (uchar*) max_str, (uchar*) max_end) != 4) - goto pad_set_lengths; - min_str+= 4; - max_str+= 4; - continue; - } - - if (wc == (my_wc_t) w_many) - { - /* - Calculate length of keys: - 'a\0\0... is the smallest possible string when we have space expand - a\ff\ff... is the biggest possible string - */ - *min_length= ((cs->state & MY_CS_BINSORT) ? - (size_t) (min_str - min_org) : - res_length); - *max_length= res_length; - goto pad_min_max; - } - - /* Normal character */ - if (my_uni_utf32(cs, wc, (uchar*) min_str, (uchar*) min_end) != 4 || - my_uni_utf32(cs, wc, (uchar*) max_str, (uchar*) max_end) != 4) - goto pad_set_lengths; - min_str+= 4; - max_str+= 4; - } - -pad_set_lengths: - *min_length= *max_length= (size_t) (min_str - min_org); - -pad_min_max: - my_fill_utf32(cs, min_str, min_end - min_str, cs->min_sort_char); - my_fill_utf32(cs, max_str, max_end - max_str, cs->max_sort_char); - return FALSE; -} - - static size_t my_scan_utf32(CHARSET_INFO *cs, const char *str, const char *end, int sequence_type) @@ -2689,7 +2491,7 @@ static MY_COLLATION_HANDLER my_collation_utf32_general_ci_handler = my_strnncollsp_utf32, my_strnxfrm_unicode, my_strnxfrmlen_utf32, - my_like_range_utf32, + my_like_range_generic, my_wildcmp_utf32_ci, my_strcasecmp_mb2_or_mb4, my_instr_mb, @@ -2705,7 +2507,7 @@ static MY_COLLATION_HANDLER my_collation_utf32_bin_handler = my_strnncollsp_utf32_bin, my_strnxfrm_unicode_full_bin, my_strnxfrmlen_unicode_full_bin, - my_like_range_utf32, + my_like_range_generic, my_wildcmp_utf32_bin, my_strcasecmp_mb2_or_mb4, my_instr_mb, @@ -3252,120 +3054,6 @@ void my_hash_sort_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)), } } -/* -** Calculate min_str and max_str that ranges a LIKE string. -** Arguments: -** ptr Pointer to LIKE string. -** ptr_length Length of LIKE string. -** escape Escape character in LIKE. (Normally '\'). -** All escape characters should be removed from min_str and max_str -** res_length Length of min_str and max_str. -** min_str Smallest case sensitive string that ranges LIKE. -** Should be space padded to res_length. -** max_str Largest case sensitive string that ranges LIKE. -** Normally padded with the biggest character sort value. -** -** The function should return 0 if ok and 1 if the LIKE string can't be -** optimized ! -*/ - -my_bool my_like_range_ucs2(CHARSET_INFO *cs, - const char *ptr, size_t ptr_length, - pbool escape, pbool w_one, pbool w_many, - size_t res_length, - char *min_str,char *max_str, - size_t *min_length,size_t *max_length) -{ - const char *end=ptr+ptr_length; - char *min_org=min_str; - char *min_end=min_str+res_length; - size_t charlen= res_length / cs->mbmaxlen; - const char *contraction_flags= cs->contractions ? - ((const char*) cs->contractions) + 0x40*0x40 : NULL; - - for ( ; ptr + 1 < end && min_str + 1 < min_end && charlen > 0 - ; ptr+=2, charlen--) - { - if (ptr[0] == '\0' && ptr[1] == escape && ptr + 1 < end) - { - ptr+=2; /* Skip escape */ - *min_str++= *max_str++ = ptr[0]; - *min_str++= *max_str++ = ptr[1]; - continue; - } - if (ptr[0] == '\0' && ptr[1] == w_one) /* '_' in SQL */ - { - *min_str++= (char) (cs->min_sort_char >> 8); - *min_str++= (char) (cs->min_sort_char & 255); - *max_str++= (char) (cs->max_sort_char >> 8); - *max_str++= (char) (cs->max_sort_char & 255); - continue; - } - if (ptr[0] == '\0' && ptr[1] == w_many) /* '%' in SQL */ - { -fill_max_and_min: - /* - Calculate length of keys: - 'a\0\0... is the smallest possible string when we have space expand - a\ff\ff... is the biggest possible string - */ - *min_length= ((cs->state & MY_CS_BINSORT) ? (size_t) (min_str - min_org) : - res_length); - *max_length= res_length; - do { - *min_str++ = 0; - *min_str++ = 0; - *max_str++ = (char) (cs->max_sort_char >> 8); - *max_str++ = (char) (cs->max_sort_char & 255); - } while (min_str + 1 < min_end); - return 0; - } - - if (contraction_flags && ptr + 3 < end && - ptr[0] == '\0' && contraction_flags[(uchar) ptr[1]]) - { - /* Contraction head found */ - if (ptr[2] == '\0' && (ptr[3] == w_one || ptr[3] == w_many)) - { - /* Contraction head followed by a wildcard, quit */ - goto fill_max_and_min; - } - - /* - Check if the second letter can be contraction part, - and if two letters really produce a contraction. - */ - if (ptr[2] == '\0' && contraction_flags[(uchar) ptr[3]] && - cs->contractions[(ptr[1]-0x40)*0x40 + ptr[3] - 0x40]) - { - /* Contraction found */ - if (charlen == 1 || min_str + 2 >= min_end) - { - /* Full contraction doesn't fit, quit */ - goto fill_max_and_min; - } - - /* Put contraction head */ - *min_str++= *max_str++= *ptr++; - *min_str++= *max_str++= *ptr++; - charlen--; - } - } - /* Put contraction tail, or a single character */ - *min_str++= *max_str++ = ptr[0]; - *min_str++= *max_str++ = ptr[1]; - } - - *min_length= *max_length = (size_t) (min_str - min_org); - while (min_str + 1 < min_end) - { - *min_str++ = *max_str++ = '\0'; - *min_str++ = *max_str++ = ' '; /* Because if key compression */ - } - return 0; -} - - static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler = { @@ -3374,7 +3062,7 @@ static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler = my_strnncollsp_ucs2, my_strnxfrm_unicode, my_strnxfrmlen_simple, - my_like_range_ucs2, + my_like_range_generic, my_wildcmp_ucs2_ci, my_strcasecmp_mb2_or_mb4, my_instr_mb, @@ -3390,7 +3078,7 @@ static MY_COLLATION_HANDLER my_collation_ucs2_bin_handler = my_strnncollsp_ucs2_bin, my_strnxfrm_unicode, my_strnxfrmlen_simple, - my_like_range_ucs2, + my_like_range_generic, my_wildcmp_ucs2_bin, my_strcasecmp_mb2_or_mb4, my_instr_mb, From 7c6151ff18881034b1dee60eb4a72221a41b5b71 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 26 Nov 2010 13:59:39 +0100 Subject: [PATCH 025/110] Bug #58515 Tests: use use exec echo, not write_file to write mysqld.1.expect Fixed as suggested in the .inc file and two tests Could not reproduce problem, but tested tests on Windows --- .../extra/rpl_tests/rpl_get_master_version_and_clock.test | 8 ++------ mysql-test/include/restart_mysqld.inc | 8 ++------ mysql-test/suite/rpl/t/rpl_trigger.test | 8 ++------ 3 files changed, 6 insertions(+), 18 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 40e155bc314..c7e3d1abc03 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 @@ -53,9 +53,7 @@ source include/wait_for_slave_to_start.inc; connection master; # Write file to make mysql-test-run.pl expect the "crash", but don't start # it until it's told to ---write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -wait -EOF +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Send shutdown to the connected server and give # it 10 seconds to die before zapping it @@ -85,9 +83,7 @@ source include/wait_for_slave_io_error.inc; eval set @@global.debug = "-d,$dbug_sync_point"; # Write file to make mysql-test-run.pl start up the server again ---append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -restart -EOF +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect connection master; # Turn on reconnect diff --git a/mysql-test/include/restart_mysqld.inc b/mysql-test/include/restart_mysqld.inc index 0f363ff1ee3..d92115f0a61 100644 --- a/mysql-test/include/restart_mysqld.inc +++ b/mysql-test/include/restart_mysqld.inc @@ -1,18 +1,14 @@ # Write file to make mysql-test-run.pl expect the "crash", but don't start # it until it's told to ---write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -wait -EOF +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Send shutdown to the connected server and give # it 10 seconds to die before zapping it shutdown_server 10; # Write file to make mysql-test-run.pl start up the server again ---append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -restart -EOF +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Turn on reconnect --enable_reconnect diff --git a/mysql-test/suite/rpl/t/rpl_trigger.test b/mysql-test/suite/rpl/t/rpl_trigger.test index e296da01bad..afa80e9c3f5 100644 --- a/mysql-test/suite/rpl/t/rpl_trigger.test +++ b/mysql-test/suite/rpl/t/rpl_trigger.test @@ -313,9 +313,7 @@ FLUSH LOGS; # Stop master server --echo --> Stop master server ---write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -wait -EOF +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server 10 --source include/wait_until_disconnected.inc # Replace binlog @@ -323,9 +321,7 @@ remove_file $MYSQLD_DATADIR/master-bin.000001; copy_file $MYSQL_TEST_DIR/std_data/bug16266.000001 $MYSQLD_DATADIR/master-bin.000001; --echo --> Start master server ---append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -restart -EOF +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc let $binlog_version= query_get_value(SHOW BINLOG EVENTS, Info, 1); From 8629024b23b0bef13fb7124da50901364406edb6 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Fri, 26 Nov 2010 19:27:59 +0530 Subject: [PATCH 026/110] Bug #54899 : --one-database option cannot handle DROP/CREATE DATABASE commands After dropping and recreating the database specified along with --one-database option at command line, mysql client keeps filtering the statements even after the execution of a 'USE' command on the same database. --one-database option enables the filtering of statements when the current database is not the one specified at the command line. However, when the same database is dropped and recreated the variable (current_db) that holds the inital database name gets altered. This bug exploits the fact that current_db initially gets set to null value (0) when a 'use db_name' follows the recreation of same database db_name (speficied at the command line) and hence skip_updates gets set to 1, which inturn triggers the further filtering of statements. Fixed by making get_current_db() a no-op function when one_database is set, and hence, under that condition current_db will not get altered. Note, however the value of current_db can change when we execute 'connect' command with a differnet database to reconnect to the server, in which case, the behavior of --one-database will be formulated using this new database. --- client/mysql.cc | 8 ++- mysql-test/r/mysql.result | 71 +++++++++++++++++++ mysql-test/t/mysql.test | 144 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+), 2 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 4c2c75dc79a..dafe76a2401 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1449,8 +1449,8 @@ static struct my_option my_long_options[] = &opt_sigint_ignore, &opt_sigint_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"one-database", 'o', - "Only update the default database. This is useful for skipping updates " - "to other database in the update log.", + "Ignore statements except those that occur while the default " + "database is the one named at the command line.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef USE_POPEN {"pager", OPT_PAGER, @@ -2736,6 +2736,10 @@ static void get_current_db() { MYSQL_RES *res; + /* If one_database is set, current_db is not supposed to change. */ + if (one_database) + return; + my_free(current_db, MYF(MY_ALLOW_ZERO_PTR)); current_db= NULL; /* In case of error below current_db will be NULL */ diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 68f30ed80f8..cc3f94528f7 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -235,4 +235,75 @@ Bug #47147: mysql client option --skip-column-names does not apply to vertical o *************************** 1. row *************************** 1 +# +# Bug #54899: --one-database option cannot handle DROP/CREATE DATABASE +# commands. +# +CREATE DATABASE connected_db; +USE connected_db; +SHOW TABLES; +Tables_in_connected_db +table_in_connected_db +DROP DATABASE connected_db; + +# +# Testing --one-database option +# +CREATE DATABASE connected_db; +SHOW TABLES IN connected_db; +Tables_in_connected_db +t1 +SHOW TABLES IN test; +Tables_in_test +t1 +USE test; +DROP TABLE t1; +DROP DATABASE connected_db; + +SHOW TABLES IN test; +Tables_in_test +SHOW TABLES IN test1; +Tables_in_test1 +DROP DATABASE test1; + +# +# Checking --one-database option followed by the execution of +# connect command. +# +CREATE DATABASE connected_db; +SHOW TABLES IN connected_db; +Tables_in_connected_db +t1 +t2 +SHOW TABLES IN test; +Tables_in_test +t1 +t2 +DROP TABLE test.t1; +DROP TABLE test.t2; +DROP DATABASE connected_db; + +# +# Checking --one-database option with no database specified +# at command-line. +# +SHOW TABLES IN test; +Tables_in_test + +# +# Checking --one-database option with non_existent_db +# specified with USE command +# +SHOW TABLES IN test; +Tables_in_test +table_in_test +DROP DATABASE test; + +CREATE DATABASE test; +SHOW TABLES IN test; +Tables_in_test +table_in_test +DROP DATABASE test; +CREATE DATABASE test; + End of tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index d32d0996490..5e26e0b7ef5 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -412,5 +412,149 @@ drop table t1; --echo --exec $MYSQL --skip-column-names --vertical test -e "select 1 as a" +--echo + +--echo # +--echo # Bug #54899: --one-database option cannot handle DROP/CREATE DATABASE +--echo # commands. +--echo # +--write_file $MYSQLTEST_VARDIR/tmp/bug54899.sql +DROP DATABASE connected_db; +CREATE DATABASE connected_db; +USE connected_db; +CREATE TABLE `table_in_connected_db`(a INT); +EOF + +CREATE DATABASE connected_db; +--exec $MYSQL --one-database connected_db < $MYSQLTEST_VARDIR/tmp/bug54899.sql +USE connected_db; +SHOW TABLES; +DROP DATABASE connected_db; +--remove_file $MYSQLTEST_VARDIR/tmp/bug54899.sql + +--echo + +--echo # +--echo # Testing --one-database option +--echo # +--write_file $MYSQLTEST_VARDIR/tmp/one_db.sql +CREATE TABLE t1 (i INT); +CREATE TABLE test.t1 (i INT); +USE test; +# Following statements should be filtered. +CREATE TABLE connected_db.t2 (i INT); +CREATE TABLE t2 (i INT); +EOF + +CREATE DATABASE connected_db; +--exec $MYSQL --one-database connected_db < $MYSQLTEST_VARDIR/tmp/one_db.sql +SHOW TABLES IN connected_db; +SHOW TABLES IN test; +USE test; +DROP TABLE t1; +DROP DATABASE connected_db; +--remove_file $MYSQLTEST_VARDIR/tmp/one_db.sql + +--echo +--write_file $MYSQLTEST_VARDIR/tmp/one_db.sql +CREATE DATABASE test1; +USE test1; +USE test1; +# Following statements should be filtered. +CREATE TABLE connected_db.t1 (i INT); +EOF + +--exec $MYSQL --one-database test < $MYSQLTEST_VARDIR/tmp/one_db.sql +SHOW TABLES IN test; +SHOW TABLES IN test1; +DROP DATABASE test1; +--remove_file $MYSQLTEST_VARDIR/tmp/one_db.sql + +--echo + +--echo # +--echo # Checking --one-database option followed by the execution of +--echo # connect command. +--echo # +--write_file $MYSQLTEST_VARDIR/tmp/one_db.sql +CREATE TABLE t1 (i INT); +CREATE TABLE test.t1 (i INT); +CONNECT test; +CREATE TABLE connected_db.t2 (i INT); +CREATE TABLE t2 (i INT); +USE connected_db; +# Following statements should be filtered. +CREATE TABLE connected_db.t3 (i INT); +CREATE TABLE t3 (i INT); +EOF + +CREATE DATABASE connected_db; +--exec $MYSQL --one-database connected_db < $MYSQLTEST_VARDIR/tmp/one_db.sql +SHOW TABLES IN connected_db; +SHOW TABLES IN test; +DROP TABLE test.t1; +DROP TABLE test.t2; +DROP DATABASE connected_db; +--remove_file $MYSQLTEST_VARDIR/tmp/one_db.sql + +--echo + +--echo # +--echo # Checking --one-database option with no database specified +--echo # at command-line. +--echo # +--write_file $MYSQLTEST_VARDIR/tmp/one_db.sql +# All following statements should be filtered. +CREATE TABLE t1 (i INT); +CREATE TABLE test.t1 (i INT); +USE test; +CREATE TABLE test.t2 (i INT); +CREATE TABLE t2 (i INT); +EOF + +--exec $MYSQL --one-database < $MYSQLTEST_VARDIR/tmp/one_db.sql +SHOW TABLES IN test; +--remove_file $MYSQLTEST_VARDIR/tmp/one_db.sql + +--echo + +--echo # +--echo # Checking --one-database option with non_existent_db +--echo # specified with USE command +--echo # + +# CASE 1 : When 'test' database exists and passed at commandline. +--write_file $MYSQLTEST_VARDIR/tmp/one_db_1.sql +CREATE TABLE `table_in_test`(i INT); +USE non_existent_db; +# Following statement should be filtered out. +CREATE TABLE `table_in_non_existent_db`(i INT); +EOF + +# CASE 2 : When 'test' database exists but dropped and recreated in load file. +--write_file $MYSQLTEST_VARDIR/tmp/one_db_2.sql +DROP DATABASE test; +CREATE DATABASE test; +USE non_existent_db; +# Following statements should be filtered out. +CREATE TABLE `table_in_non_existent_db`(i INT); +USE test; +# Following statements should not be filtered out. +CREATE TABLE `table_in_test`(i INT); +EOF + +--exec $MYSQL --one-database test < $MYSQLTEST_VARDIR/tmp/one_db_1.sql +SHOW TABLES IN test; +DROP DATABASE test; +--echo +CREATE DATABASE test; +--exec $MYSQL --one-database test < $MYSQLTEST_VARDIR/tmp/one_db_2.sql +SHOW TABLES IN test; +DROP DATABASE test; +CREATE DATABASE test; + +--remove_file $MYSQLTEST_VARDIR/tmp/one_db_1.sql +--remove_file $MYSQLTEST_VARDIR/tmp/one_db_2.sql + --echo --echo End of tests From bd3a5831f6aa7471aaab14f8786cc3d16b96c7f3 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 26 Nov 2010 16:58:54 +0300 Subject: [PATCH 027/110] Bug#56639 Character Euro (0x88) not converted from cp1251 to utf8 Problem: MySQL cp1251 did not support 'U+20AC EURO SIGN' which was assigned a few years ago to 0x88. Fix: adding mapping: 0x88 <-> U+20AC @ mysql-test/include/ctype_8bit.inc New shared file to test 8bit character sets. @ mysql-test/r/ctype_cp1251.result @ mysql-test/t/ctype_cp1251.test Adding tests @ sql/share/charsets/cp1251.xml Adding mapping @ strings/ctype-extra.c Regenerating ctype-extra.c using strings/conf_to_src according to new cp1251.xml --- mysql-test/include/ctype_8bit.inc | 46 +++++ mysql-test/r/ctype_cp1251.result | 308 ++++++++++++++++++++++++++++++ mysql-test/t/ctype_cp1251.test | 10 + sql/share/charsets/cp1251.xml | 2 +- strings/ctype-extra.c | 10 +- 5 files changed, 370 insertions(+), 6 deletions(-) create mode 100644 mysql-test/include/ctype_8bit.inc diff --git a/mysql-test/include/ctype_8bit.inc b/mysql-test/include/ctype_8bit.inc new file mode 100644 index 00000000000..7259db54d05 --- /dev/null +++ b/mysql-test/include/ctype_8bit.inc @@ -0,0 +1,46 @@ +# +# Test Unicode conversion, upper, lower +# +SELECT @@collation_connection; +CREATE TABLE t1 AS SELECT ' ' AS a LIMIT 0; +INSERT INTO t1 VALUES (0x00),(0x01),(0x02),(0x03),(0x04),(0x05),(0x06),(0x07); +INSERT INTO t1 VALUES (0x08),(0x09),(0x0A),(0x0B),(0x0C),(0x0D),(0x0E),(0x0F); +INSERT INTO t1 VALUES (0x10),(0x11),(0x12),(0x13),(0x14),(0x15),(0x16),(0x17); +INSERT INTO t1 VALUES (0x18),(0x19),(0x1A),(0x1B),(0x1C),(0x1D),(0x1E),(0x1F); +INSERT INTO t1 VALUES (0x20),(0x21),(0x22),(0x23),(0x24),(0x25),(0x26),(0x27); +INSERT INTO t1 VALUES (0x28),(0x29),(0x2A),(0x2B),(0x2C),(0x2D),(0x2E),(0x2F); +INSERT INTO t1 VALUES (0x30),(0x31),(0x32),(0x33),(0x34),(0x35),(0x36),(0x37); +INSERT INTO t1 VALUES (0x38),(0x39),(0x3A),(0x3B),(0x3C),(0x3D),(0x3E),(0x3F); +INSERT INTO t1 VALUES (0x40),(0x41),(0x42),(0x43),(0x44),(0x45),(0x46),(0x47); +INSERT INTO t1 VALUES (0x48),(0x49),(0x4A),(0x4B),(0x4C),(0x4D),(0x4E),(0x4F); +INSERT INTO t1 VALUES (0x50),(0x51),(0x52),(0x53),(0x54),(0x55),(0x56),(0x57); +INSERT INTO t1 VALUES (0x58),(0x59),(0x5A),(0x5B),(0x5C),(0x5D),(0x5E),(0x5F); +INSERT INTO t1 VALUES (0x60),(0x61),(0x62),(0x63),(0x64),(0x65),(0x66),(0x67); +INSERT INTO t1 VALUES (0x68),(0x69),(0x6A),(0x6B),(0x6C),(0x6D),(0x6E),(0x6F); +INSERT INTO t1 VALUES (0x70),(0x71),(0x72),(0x73),(0x74),(0x75),(0x76),(0x77); +INSERT INTO t1 VALUES (0x78),(0x79),(0x7A),(0x7B),(0x7C),(0x7D),(0x7E),(0x7F); +INSERT INTO t1 VALUES (0x80),(0x81),(0x82),(0x83),(0x84),(0x85),(0x86),(0x87); +INSERT INTO t1 VALUES (0x88),(0x89),(0x8A),(0x8B),(0x8C),(0x8D),(0x8E),(0x8F); +INSERT INTO t1 VALUES (0x90),(0x91),(0x92),(0x93),(0x94),(0x95),(0x96),(0x97); +INSERT INTO t1 VALUES (0x98),(0x99),(0x9A),(0x9B),(0x9C),(0x9D),(0x9E),(0x9F); +INSERT INTO t1 VALUES (0xA0),(0xA1),(0xA2),(0xA3),(0xA4),(0xA5),(0xA6),(0xA7); +INSERT INTO t1 VALUES (0xA8),(0xA9),(0xAA),(0xAB),(0xAC),(0xAD),(0xAE),(0xAF); +INSERT INTO t1 VALUES (0xB0),(0xB1),(0xB2),(0xB3),(0xB4),(0xB5),(0xB6),(0xB7); +INSERT INTO t1 VALUES (0xB8),(0xB9),(0xBA),(0xBB),(0xBC),(0xBD),(0xBE),(0xBF); +INSERT INTO t1 VALUES (0xC0),(0xC1),(0xC2),(0xC3),(0xC4),(0xC5),(0xC6),(0xC7); +INSERT INTO t1 VALUES (0xC8),(0xC9),(0xCA),(0xCB),(0xCC),(0xCD),(0xCE),(0xCF); +INSERT INTO t1 VALUES (0xD0),(0xD1),(0xD2),(0xD3),(0xD4),(0xD5),(0xD6),(0xD7); +INSERT INTO t1 VALUES (0xD8),(0xD9),(0xDA),(0xDB),(0xDC),(0xDD),(0xDE),(0xDF); +INSERT INTO t1 VALUES (0xE0),(0xE1),(0xE2),(0xE3),(0xE4),(0xE5),(0xE6),(0xE7); +INSERT INTO t1 VALUES (0xE8),(0xE9),(0xEA),(0xEB),(0xEC),(0xED),(0xEE),(0xEF); +INSERT INTO t1 VALUES (0xF0),(0xF1),(0xF2),(0xF3),(0xF4),(0xF5),(0xF6),(0xF7); +INSERT INTO t1 VALUES (0xF8),(0xF9),(0xFA),(0xFB),(0xFC),(0xFD),(0xFE),(0xFF); +SELECT + HEX(a) AS chr, + HEX(LOWER(a)) AS upper, + HEX(LOWER(a)) AS lower, + HEX(@utf8:=CONVERT(a USING utf8)) AS utf8, + HEX(@roundtrip:=CAST(@utf8 AS CHAR)) AS roundtrip, + if(a=BINARY @roundtrip,'','Round trip unsafe') AS issafe +FROM t1 ORDER BY chr; +DROP TABLE t1; diff --git a/mysql-test/r/ctype_cp1251.result b/mysql-test/r/ctype_cp1251.result index 47797af3cbe..dc12f9ceb03 100644 --- a/mysql-test/r/ctype_cp1251.result +++ b/mysql-test/r/ctype_cp1251.result @@ -70,3 +70,311 @@ we_ivo NULL we_martin NULL we_toshko NULL drop table t1; +# +# Start of 5.1 tests +# +SELECT @@collation_connection; +@@collation_connection +cp1251_general_ci +CREATE TABLE t1 AS SELECT ' ' AS a LIMIT 0; +INSERT INTO t1 VALUES (0x00),(0x01),(0x02),(0x03),(0x04),(0x05),(0x06),(0x07); +INSERT INTO t1 VALUES (0x08),(0x09),(0x0A),(0x0B),(0x0C),(0x0D),(0x0E),(0x0F); +INSERT INTO t1 VALUES (0x10),(0x11),(0x12),(0x13),(0x14),(0x15),(0x16),(0x17); +INSERT INTO t1 VALUES (0x18),(0x19),(0x1A),(0x1B),(0x1C),(0x1D),(0x1E),(0x1F); +INSERT INTO t1 VALUES (0x20),(0x21),(0x22),(0x23),(0x24),(0x25),(0x26),(0x27); +INSERT INTO t1 VALUES (0x28),(0x29),(0x2A),(0x2B),(0x2C),(0x2D),(0x2E),(0x2F); +INSERT INTO t1 VALUES (0x30),(0x31),(0x32),(0x33),(0x34),(0x35),(0x36),(0x37); +INSERT INTO t1 VALUES (0x38),(0x39),(0x3A),(0x3B),(0x3C),(0x3D),(0x3E),(0x3F); +INSERT INTO t1 VALUES (0x40),(0x41),(0x42),(0x43),(0x44),(0x45),(0x46),(0x47); +INSERT INTO t1 VALUES (0x48),(0x49),(0x4A),(0x4B),(0x4C),(0x4D),(0x4E),(0x4F); +INSERT INTO t1 VALUES (0x50),(0x51),(0x52),(0x53),(0x54),(0x55),(0x56),(0x57); +INSERT INTO t1 VALUES (0x58),(0x59),(0x5A),(0x5B),(0x5C),(0x5D),(0x5E),(0x5F); +INSERT INTO t1 VALUES (0x60),(0x61),(0x62),(0x63),(0x64),(0x65),(0x66),(0x67); +INSERT INTO t1 VALUES (0x68),(0x69),(0x6A),(0x6B),(0x6C),(0x6D),(0x6E),(0x6F); +INSERT INTO t1 VALUES (0x70),(0x71),(0x72),(0x73),(0x74),(0x75),(0x76),(0x77); +INSERT INTO t1 VALUES (0x78),(0x79),(0x7A),(0x7B),(0x7C),(0x7D),(0x7E),(0x7F); +INSERT INTO t1 VALUES (0x80),(0x81),(0x82),(0x83),(0x84),(0x85),(0x86),(0x87); +INSERT INTO t1 VALUES (0x88),(0x89),(0x8A),(0x8B),(0x8C),(0x8D),(0x8E),(0x8F); +INSERT INTO t1 VALUES (0x90),(0x91),(0x92),(0x93),(0x94),(0x95),(0x96),(0x97); +INSERT INTO t1 VALUES (0x98),(0x99),(0x9A),(0x9B),(0x9C),(0x9D),(0x9E),(0x9F); +INSERT INTO t1 VALUES (0xA0),(0xA1),(0xA2),(0xA3),(0xA4),(0xA5),(0xA6),(0xA7); +INSERT INTO t1 VALUES (0xA8),(0xA9),(0xAA),(0xAB),(0xAC),(0xAD),(0xAE),(0xAF); +INSERT INTO t1 VALUES (0xB0),(0xB1),(0xB2),(0xB3),(0xB4),(0xB5),(0xB6),(0xB7); +INSERT INTO t1 VALUES (0xB8),(0xB9),(0xBA),(0xBB),(0xBC),(0xBD),(0xBE),(0xBF); +INSERT INTO t1 VALUES (0xC0),(0xC1),(0xC2),(0xC3),(0xC4),(0xC5),(0xC6),(0xC7); +INSERT INTO t1 VALUES (0xC8),(0xC9),(0xCA),(0xCB),(0xCC),(0xCD),(0xCE),(0xCF); +INSERT INTO t1 VALUES (0xD0),(0xD1),(0xD2),(0xD3),(0xD4),(0xD5),(0xD6),(0xD7); +INSERT INTO t1 VALUES (0xD8),(0xD9),(0xDA),(0xDB),(0xDC),(0xDD),(0xDE),(0xDF); +INSERT INTO t1 VALUES (0xE0),(0xE1),(0xE2),(0xE3),(0xE4),(0xE5),(0xE6),(0xE7); +INSERT INTO t1 VALUES (0xE8),(0xE9),(0xEA),(0xEB),(0xEC),(0xED),(0xEE),(0xEF); +INSERT INTO t1 VALUES (0xF0),(0xF1),(0xF2),(0xF3),(0xF4),(0xF5),(0xF6),(0xF7); +INSERT INTO t1 VALUES (0xF8),(0xF9),(0xFA),(0xFB),(0xFC),(0xFD),(0xFE),(0xFF); +SELECT +HEX(a) AS chr, +HEX(LOWER(a)) AS upper, +HEX(LOWER(a)) AS lower, +HEX(@utf8:=CONVERT(a USING utf8)) AS utf8, +HEX(@roundtrip:=CAST(@utf8 AS CHAR)) AS roundtrip, +if(a=BINARY @roundtrip,'','Round trip unsafe') AS issafe +FROM t1 ORDER BY chr; +chr upper lower utf8 roundtrip issafe +00 00 00 00 00 +01 01 01 01 01 +02 02 02 02 02 +03 03 03 03 03 +04 04 04 04 04 +05 05 05 05 05 +06 06 06 06 06 +07 07 07 07 07 +08 08 08 08 08 +09 09 09 09 09 +0A 0A 0A 0A 0A +0B 0B 0B 0B 0B +0C 0C 0C 0C 0C +0D 0D 0D 0D 0D +0E 0E 0E 0E 0E +0F 0F 0F 0F 0F +10 10 10 10 10 +11 11 11 11 11 +12 12 12 12 12 +13 13 13 13 13 +14 14 14 14 14 +15 15 15 15 15 +16 16 16 16 16 +17 17 17 17 17 +18 18 18 18 18 +19 19 19 19 19 +1A 1A 1A 1A 1A +1B 1B 1B 1B 1B +1C 1C 1C 1C 1C +1D 1D 1D 1D 1D +1E 1E 1E 1E 1E +1F 1F 1F 1F 1F +20 20 20 20 20 +21 21 21 21 21 +22 22 22 22 22 +23 23 23 23 23 +24 24 24 24 24 +25 25 25 25 25 +26 26 26 26 26 +27 27 27 27 27 +28 28 28 28 28 +29 29 29 29 29 +2A 2A 2A 2A 2A +2B 2B 2B 2B 2B +2C 2C 2C 2C 2C +2D 2D 2D 2D 2D +2E 2E 2E 2E 2E +2F 2F 2F 2F 2F +30 30 30 30 30 +31 31 31 31 31 +32 32 32 32 32 +33 33 33 33 33 +34 34 34 34 34 +35 35 35 35 35 +36 36 36 36 36 +37 37 37 37 37 +38 38 38 38 38 +39 39 39 39 39 +3A 3A 3A 3A 3A +3B 3B 3B 3B 3B +3C 3C 3C 3C 3C +3D 3D 3D 3D 3D +3E 3E 3E 3E 3E +3F 3F 3F 3F 3F +40 40 40 40 40 +41 61 61 41 41 +42 62 62 42 42 +43 63 63 43 43 +44 64 64 44 44 +45 65 65 45 45 +46 66 66 46 46 +47 67 67 47 47 +48 68 68 48 48 +49 69 69 49 49 +4A 6A 6A 4A 4A +4B 6B 6B 4B 4B +4C 6C 6C 4C 4C +4D 6D 6D 4D 4D +4E 6E 6E 4E 4E +4F 6F 6F 4F 4F +50 70 70 50 50 +51 71 71 51 51 +52 72 72 52 52 +53 73 73 53 53 +54 74 74 54 54 +55 75 75 55 55 +56 76 76 56 56 +57 77 77 57 57 +58 78 78 58 58 +59 79 79 59 59 +5A 7A 7A 5A 5A +5B 5B 5B 5B 5B +5C 5C 5C 5C 5C +5D 5D 5D 5D 5D +5E 5E 5E 5E 5E +5F 5F 5F 5F 5F +60 60 60 60 60 +61 61 61 61 61 +62 62 62 62 62 +63 63 63 63 63 +64 64 64 64 64 +65 65 65 65 65 +66 66 66 66 66 +67 67 67 67 67 +68 68 68 68 68 +69 69 69 69 69 +6A 6A 6A 6A 6A +6B 6B 6B 6B 6B +6C 6C 6C 6C 6C +6D 6D 6D 6D 6D +6E 6E 6E 6E 6E +6F 6F 6F 6F 6F +70 70 70 70 70 +71 71 71 71 71 +72 72 72 72 72 +73 73 73 73 73 +74 74 74 74 74 +75 75 75 75 75 +76 76 76 76 76 +77 77 77 77 77 +78 78 78 78 78 +79 79 79 79 79 +7A 7A 7A 7A 7A +7B 7B 7B 7B 7B +7C 7C 7C 7C 7C +7D 7D 7D 7D 7D +7E 7E 7E 7E 7E +7F 7F 7F 7F 7F +80 90 90 D082 80 +81 83 83 D083 81 +82 82 82 E2809A 82 +83 83 83 D193 83 +84 84 84 E2809E 84 +85 85 85 E280A6 85 +86 86 86 E280A0 86 +87 87 87 E280A1 87 +88 88 88 E282AC 88 +89 89 89 E280B0 89 +8A 9A 9A D089 8A +8B 8B 8B E280B9 8B +8C 9C 9C D08A 8C +8D 9D 9D D08C 8D +8E 9E 9E D08B 8E +8F 9F 9F D08F 8F +90 90 90 D192 90 +91 91 91 E28098 91 +92 92 92 E28099 92 +93 93 93 E2809C 93 +94 94 94 E2809D 94 +95 95 95 E280A2 95 +96 96 96 E28093 96 +97 97 97 E28094 97 +98 98 98 3F 3F Round trip unsafe +99 99 99 E284A2 99 +9A 9A 9A D199 9A +9B 9B 9B E280BA 9B +9C 9C 9C D19A 9C +9D 9D 9D D19C 9D +9E 9E 9E D19B 9E +9F 9F 9F D19F 9F +A0 A0 A0 C2A0 A0 +A1 A2 A2 D08E A1 +A2 A2 A2 D19E A2 +A3 BC BC D088 A3 +A4 A4 A4 C2A4 A4 +A5 B4 B4 D290 A5 +A6 A6 A6 C2A6 A6 +A7 A7 A7 C2A7 A7 +A8 B8 B8 D081 A8 +A9 A9 A9 C2A9 A9 +AA BA BA D084 AA +AB AB AB C2AB AB +AC AC AC C2AC AC +AD AD AD C2AD AD +AE AE AE C2AE AE +AF BF BF D087 AF +B0 B0 B0 C2B0 B0 +B1 B1 B1 C2B1 B1 +B2 B3 B3 D086 B2 +B3 B3 B3 D196 B3 +B4 B4 B4 D291 B4 +B5 B5 B5 C2B5 B5 +B6 B6 B6 C2B6 B6 +B7 B7 B7 C2B7 B7 +B8 B8 B8 D191 B8 +B9 B9 B9 E28496 B9 +BA BA BA D194 BA +BB BB BB C2BB BB +BC BC BC D198 BC +BD BE BE D085 BD +BE BE BE D195 BE +BF BF BF D197 BF +C0 E0 E0 D090 C0 +C1 E1 E1 D091 C1 +C2 E2 E2 D092 C2 +C3 E3 E3 D093 C3 +C4 E4 E4 D094 C4 +C5 E5 E5 D095 C5 +C6 E6 E6 D096 C6 +C7 E7 E7 D097 C7 +C8 E8 E8 D098 C8 +C9 E9 E9 D099 C9 +CA EA EA D09A CA +CB EB EB D09B CB +CC EC EC D09C CC +CD ED ED D09D CD +CE EE EE D09E CE +CF EF EF D09F CF +D0 F0 F0 D0A0 D0 +D1 F1 F1 D0A1 D1 +D2 F2 F2 D0A2 D2 +D3 F3 F3 D0A3 D3 +D4 F4 F4 D0A4 D4 +D5 F5 F5 D0A5 D5 +D6 F6 F6 D0A6 D6 +D7 F7 F7 D0A7 D7 +D8 F8 F8 D0A8 D8 +D9 F9 F9 D0A9 D9 +DA FA FA D0AA DA +DB FB FB D0AB DB +DC FC FC D0AC DC +DD FD FD D0AD DD +DE FE FE D0AE DE +DF FF FF D0AF DF +E0 E0 E0 D0B0 E0 +E1 E1 E1 D0B1 E1 +E2 E2 E2 D0B2 E2 +E3 E3 E3 D0B3 E3 +E4 E4 E4 D0B4 E4 +E5 E5 E5 D0B5 E5 +E6 E6 E6 D0B6 E6 +E7 E7 E7 D0B7 E7 +E8 E8 E8 D0B8 E8 +E9 E9 E9 D0B9 E9 +EA EA EA D0BA EA +EB EB EB D0BB EB +EC EC EC D0BC EC +ED ED ED D0BD ED +EE EE EE D0BE EE +EF EF EF D0BF EF +F0 F0 F0 D180 F0 +F1 F1 F1 D181 F1 +F2 F2 F2 D182 F2 +F3 F3 F3 D183 F3 +F4 F4 F4 D184 F4 +F5 F5 F5 D185 F5 +F6 F6 F6 D186 F6 +F7 F7 F7 D187 F7 +F8 F8 F8 D188 F8 +F9 F9 F9 D189 F9 +FA FA FA D18A FA +FB FB FB D18B FB +FC FC FC D18C FC +FD FD FD D18D FD +FE FE FE D18E FE +FF FF FF D18F FF +DROP TABLE t1; +# +# End of 5.1 tests +# diff --git a/mysql-test/t/ctype_cp1251.test b/mysql-test/t/ctype_cp1251.test index 463a9cea4bc..2331c731061 100644 --- a/mysql-test/t/ctype_cp1251.test +++ b/mysql-test/t/ctype_cp1251.test @@ -48,3 +48,13 @@ select * from t1 where a like 'we_%'; drop table t1; # End of 4.1 tests + +--echo # +--echo # Start of 5.1 tests +--echo # + +--source include/ctype_8bit.inc + +--echo # +--echo # End of 5.1 tests +--echo # diff --git a/sql/share/charsets/cp1251.xml b/sql/share/charsets/cp1251.xml index b80db9f8ec0..06ba8a5a4b9 100644 --- a/sql/share/charsets/cp1251.xml +++ b/sql/share/charsets/cp1251.xml @@ -98,7 +98,7 @@ 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F - 0402 0403 201A 0453 201E 2026 2020 2021 0000 2030 0409 2039 040A 040C 040B 040F + 0402 0403 201A 0453 201E 2026 2020 2021 20AC 2030 0409 2039 040A 040C 040B 040F 0452 2018 2019 201C 201D 2022 2013 2014 0000 2122 0459 203A 045A 045C 045B 045F 00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 diff --git a/strings/ctype-extra.c b/strings/ctype-extra.c index 75244e40435..bc8c5342a52 100644 --- a/strings/ctype-extra.c +++ b/strings/ctype-extra.c @@ -1040,7 +1040,7 @@ uint16 to_uni_cp1251_bulgarian_ci[] = { 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021, -0x0000,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, +0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 0x0000,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F, 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7, @@ -1730,7 +1730,7 @@ uint16 to_uni_cp1251_ukrainian_ci[] = { 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021, -0x0000,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, +0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 0x0000,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F, 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7, @@ -3762,7 +3762,7 @@ uint16 to_uni_cp1251_bin[] = { 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021, -0x0000,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, +0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 0x0000,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F, 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7, @@ -3877,7 +3877,7 @@ uint16 to_uni_cp1251_general_ci[] = { 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021, -0x0000,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, +0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 0x0000,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F, 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7, @@ -3992,7 +3992,7 @@ uint16 to_uni_cp1251_general_cs[] = { 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021, -0x0000,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, +0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 0x0000,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F, 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7, From e3cbf205547e4b8e34438ab7413af409a6873731 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 26 Nov 2010 16:07:07 +0100 Subject: [PATCH 028/110] Cherrypicked http://lists.mysql.com/commits/124935 MSI: Only call custom action if REMOVE=ALL is specified, this avoids accidential removing services if feature states are modified (reported by Iggy) --- packaging/WiX/mysql_server.wxs.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/WiX/mysql_server.wxs.in b/packaging/WiX/mysql_server.wxs.in index ea2ee1d9aaf..43a30538384 100644 --- a/packaging/WiX/mysql_server.wxs.in +++ b/packaging/WiX/mysql_server.wxs.in @@ -128,10 +128,10 @@ Impersonate="no" Return="check" /> - Installed And Not UPGRADINGPRODUCTCODE - Installed And Not UPGRADINGPRODUCTCODE - Installed And Not UPGRADINGPRODUCTCODE And UILevel>4 - Installed And Not UPGRADINGPRODUCTCODE And UILevel<=4 + Installed And Not UPGRADINGPRODUCTCODE And REMOVE="ALL" + Installed And Not UPGRADINGPRODUCTCODE And REMOVE="ALL" + Installed And Not UPGRADINGPRODUCTCODE And REMOVE="ALL" And UILevel>4 + Installed And Not UPGRADINGPRODUCTCODE And REMOVE="ALL" And UILevel<=4 From 0008e06489cc3c346ee4ab62f89f20ac404f9472 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 26 Nov 2010 19:59:10 -0200 Subject: [PATCH 029/110] Bug#51817: incorrect assumption: thd->query at 0x2ab2a8360360 is an invalid pointer The problem is that the logic which checks if a pointer is valid relies on a poor heuristic based on the start and end addresses of the data segment and heap. Apart from miscalculating the heap bounds, this approach also suffers from the fact that memory can come from places other than the heap. See Bug#58528 for a more detailed explanation. On Linux, the solution is to access the process's memory through /proc/self/task//mem, which allows for retrieving the contents of pages within the virtual address space of the calling process. If a address range is not mapped, a input/output error is returned. --- client/mysqltest.cc | 11 +++-- include/my_stacktrace.h | 2 +- mysys/stacktrace.c | 103 +++++++++++++++++++++++++++++++++++++--- sql/mysqld.cc | 14 +++--- 4 files changed, 112 insertions(+), 18 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 4e03ad27246..e0575a1d638 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -7782,13 +7782,16 @@ static void dump_backtrace(void) { struct st_connection *conn= cur_con; - my_safe_print_str("read_command_buf", read_command_buf, - sizeof(read_command_buf)); + fprintf(stderr, "read_command_buf (%p): ", read_command_buf); + my_safe_print_str(read_command_buf, sizeof(read_command_buf)); + if (conn) { - my_safe_print_str("conn->name", conn->name, conn->name_len); + fprintf(stderr, "conn->name (%p): ", conn->name); + my_safe_print_str(conn->name, conn->name_len); #ifdef EMBEDDED_LIBRARY - my_safe_print_str("conn->cur_query", conn->cur_query, conn->cur_query_len); + fprintf(stderr, "conn->cur_query (%p): ", conn->cur_query); + my_safe_print_str(conn->cur_query, conn->cur_query_len); #endif } fputs("Attempting backtrace...\n", stderr); diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h index 9250fd4579e..b64d5d798a5 100644 --- a/include/my_stacktrace.h +++ b/include/my_stacktrace.h @@ -47,7 +47,7 @@ C_MODE_START #if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE) void my_init_stacktrace(); void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack); -void my_safe_print_str(const char* name, const char* val, int max_len); +void my_safe_print_str(const char* val, int max_len); void my_write_core(int sig); #if BACKTRACE_DEMANGLE char *my_demangle(const char *mangled_name, int *status); diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index ebd84548a9b..b6bf88cf3e1 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -27,6 +27,11 @@ #include #include +#ifdef __linux__ +#include /* isprint */ +#include /* SYS_gettid */ +#endif + #if HAVE_EXECINFO_H #include #endif @@ -46,10 +51,96 @@ void my_init_stacktrace() #endif } -void my_safe_print_str(const char* name, const char* val, int max_len) +#ifdef __linux__ + +static void print_buffer(char *buffer, size_t count) { - char *heap_end= (char*) sbrk(0); - fprintf(stderr, "%s at %p ", name, val); + for (; count && *buffer; --count) + { + int c= (int) *buffer++; + fputc(isprint(c) ? c : ' ', stderr); + } +} + +/** + Access the pages of this process through /proc/self/task//mem + in order to safely print the contents of a memory address range. + + @param addr The address at the start of the memory region. + @param max_len The length of the memory region. + + @return Zero on success. +*/ +static int safe_print_str(const char *addr, int max_len) +{ + int fd; + pid_t tid; + off_t offset; + ssize_t nbytes= 0; + size_t total, count; + char buf[256]; + + tid= (pid_t) syscall(SYS_gettid); + + sprintf(buf, "/proc/self/task/%d/mem", tid); + + if ((fd= open(buf, O_RDONLY)) < 0) + return -1; + + total= max_len; + offset= (off_t) addr; + + /* Read up to the maximum number of bytes. */ + while (total) + { + count= min(sizeof(buf), total); + + if ((nbytes= pread(fd, buf, count, offset)) < 0) + { + /* Just in case... */ + if (errno == EINTR) + continue; + else + break; + } + + /* Advance offset into memory. */ + total-= nbytes; + offset+= nbytes; + addr+= nbytes; + + /* Output the printable characters. */ + print_buffer(buf, nbytes); + + /* Break if less than requested... */ + if ((count - nbytes)) + break; + } + + /* Output a new line if something was printed. */ + if (total != (size_t) max_len) + fputc('\n', stderr); + + if (nbytes == -1) + fprintf(stderr, "Can't read from address %p: %m.\n", addr); + + close(fd); + + return 0; +} + +#endif + +void my_safe_print_str(const char* val, int max_len) +{ + char *heap_end; + +#ifdef __linux__ + if (!safe_print_str(val, max_len)) + return; +#endif + + heap_end= (char*) sbrk(0); if (!PTR_SANE(val)) { @@ -57,7 +148,6 @@ void my_safe_print_str(const char* name, const char* val, int max_len) return; } - fprintf(stderr, "= "); for (; max_len && PTR_SANE(val) && *val; --max_len) fputc(*val++, stderr); fputc('\n', stderr); @@ -657,10 +747,9 @@ void my_write_core(int unused) } -void my_safe_print_str(const char *name, const char *val, int len) +void my_safe_print_str(const char *val, int len) { - fprintf(stderr,"%s at %p", name, val); - __try + __try { fprintf(stderr,"=%.*s\n", len, val); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 98556e87838..3a33d06fb01 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2527,7 +2527,7 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", if (!(test_flags & TEST_NO_STACKTRACE)) { - fprintf(stderr, "thd: 0x%lx\n",(long) thd); + fprintf(stderr, "Thread pointer: 0x%lx\n", (long) thd); fprintf(stderr, "Attempting backtrace. You can use the following " "information to find out\nwhere mysqld died. If " "you see no messages after this, something went\n" @@ -2555,11 +2555,13 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", kreason= "KILLED_NO_VALUE"; break; } - fprintf(stderr, "Trying to get some variables.\n\ -Some pointers may be invalid and cause the dump to abort...\n"); - my_safe_print_str("thd->query", thd->query(), 1024); - fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id); - fprintf(stderr, "thd->killed=%s\n", kreason); + fprintf(stderr, "\nTrying to get some variables.\n" + "Some pointers may be invalid and cause the dump to abort.\n"); + fprintf(stderr, "Query (%p): ", thd->query()); + my_safe_print_str(thd->query(), min(1024, thd->query_length())); + fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id); + fprintf(stderr, "Status: %s\n", kreason); + fputc('\n', stderr); } fprintf(stderr, "\ The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\ From a97677944b96f6a38b351dae4803dc5c1ee4f158 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 27 Nov 2010 02:51:14 +0100 Subject: [PATCH 030/110] Fix detection of tgoto declaration: it needs curses.h to be included before term.h on Solaris Express 11 --- cmd-line-utils/libedit/CMakeLists.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cmd-line-utils/libedit/CMakeLists.txt b/cmd-line-utils/libedit/CMakeLists.txt index b0e375dfcbd..76fcfc3204e 100644 --- a/cmd-line-utils/libedit/CMakeLists.txt +++ b/cmd-line-utils/libedit/CMakeLists.txt @@ -26,6 +26,21 @@ int main() tgoto(0,0,0); return 0; }" HAVE_DECL_TGOTO) +IF(NOT HAVE_DECL_TGOTO) + # On Solaris 11, term.h is broken, curses.h is also required. + CHECK_CXX_SOURCE_COMPILES(" + #include + #include + int main() + { + tgoto(0,0,0); + return 0; + }" HAVE_DECL_TGOTO2) + IF(HAVE_DECL_TGOTO2) + SET(HAVE_DECL_TGOTO 1 CACHE INTERNAL "" FORCE) + ENDIF() +ENDIF() + SET(CMAKE_REQUIRED_LIBRARIES) From 13c9cf26a6a76ba9516b1b4ddb09ddacceb9047a Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sat, 27 Nov 2010 11:51:07 +0000 Subject: [PATCH 031/110] BUG#58416: binlog.binlog_row_failure_mixing_engines fails on win x86 debug_max The windows MTR run exhibited a different test execution ordering (due to the fact that in these platforms MTR is invoked with --parallel > 1). This uncovered a bug in the aforementioned test case, which is triggered by the following conditions: 1. server is not restarted between two different tests; 2. the test before binlog.binlog_row_failure_mixing_engines issues flush logs; 3. binlog.binlog_row_failure_mixing_engines uses binlog positions to limit the output of show_binlog_events; 4. binlog.binlog_row_failure_mixing_engines does not state which binlog file to use, thence it uses a wrong binlog file with the correct position. There are two possible fixes: 1. make sure that the test start from a clean slate - binlog wise; 2. in addition to the position, also state the binary log file before sourcing show_binlog_events.inc . We go for fix #1, ie, deploy a RESET MASTER before the test is actually started. --- mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test | 1 + .../suite/binlog/r/binlog_mixed_failure_mixing_engines.result | 1 + .../suite/binlog/r/binlog_row_failure_mixing_engines.result | 1 + 3 files changed, 3 insertions(+) diff --git a/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test b/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test index 54f3c538c79..d537e29c1a8 100644 --- a/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test +++ b/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test @@ -60,6 +60,7 @@ # Please, remove this test case after pushing WL#2687. ################################################################################ +RESET MASTER; --echo ################################################################################### --echo # CONFIGURATION diff --git a/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result b/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result index dfc08d76a6a..4078103b1f7 100644 --- a/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result +++ b/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result @@ -1,3 +1,4 @@ +RESET MASTER; ################################################################################### # CONFIGURATION ################################################################################### diff --git a/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result b/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result index 45c8640d3e3..2d493397ffd 100644 --- a/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result +++ b/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result @@ -1,3 +1,4 @@ +RESET MASTER; ################################################################################### # CONFIGURATION ################################################################################### From abb201c131a6ea390e3f9974a603e43742c73445 Mon Sep 17 00:00:00 2001 From: Date: Sun, 28 Nov 2010 17:43:36 +0800 Subject: [PATCH 032/110] BUG#54903 BINLOG statement toggles session variables When using BINLOG statement to execute rows log events, session variables foreign_key_checks and unique_checks are changed temporarily. As each rows log event has their own special session environment and its own foreign_key_checks and unique_checks can be different from current session which executing the BINLOG statement. But these variables are not restored correctly after BINLOG statement. This problem will cause that the following statements fail or generate unexpected data. In this patch, code is added to backup and restore these two variables. So BINLOG statement will not affect current session's variables again. --- mysql-test/extra/binlog_tests/binlog.test | 53 +++++++++++++++++ .../suite/binlog/r/binlog_row_binlog.result | 59 +++++++++++++++++++ .../suite/binlog/r/binlog_stm_binlog.result | 59 +++++++++++++++++++ sql/sql_binlog.cc | 8 +++ 4 files changed, 179 insertions(+) diff --git a/mysql-test/extra/binlog_tests/binlog.test b/mysql-test/extra/binlog_tests/binlog.test index 7f48341077e..fd6ba1c17fa 100644 --- a/mysql-test/extra/binlog_tests/binlog.test +++ b/mysql-test/extra/binlog_tests/binlog.test @@ -302,5 +302,58 @@ BINLOG ' SHOW BINLOG EVENTS; DROP TABLE t1; + +--echo +--echo # BUG#54903 BINLOG statement toggles session variables +--echo # ---------------------------------------------------------------------- +--echo # This test verify that BINLOG statement doesn't change current session's +--echo # variables foreign_key_checks and unique_checks. +--echo +CREATE TABLE t1 (c1 INT KEY); + +SET @@SESSION.foreign_key_checks= ON; +SET @@SESSION.unique_checks= ON; + +--echo # INSERT INTO t1 VALUES (1) +--echo # foreign_key_checks=0 and unique_checks=0 +BINLOG ' +dfLtTBMBAAAAKQAAANcAAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE= +dfLtTBcBAAAAIgAAAPkAAAAAABcAAAAAAAcAAf/+AQAAAA== +'; + +SELECT * FROM t1; +--echo # Their values should be ON +SHOW SESSION VARIABLES LIKE "%_checks"; + +--echo +SET @@SESSION.foreign_key_checks= OFF; +SET @@SESSION.unique_checks= OFF; + +--echo # INSERT INTO t1 VALUES(2) +--echo # foreign_key_checks=1 and unique_checks=1 +BINLOG ' +dfLtTBMBAAAAKQAAAKsBAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE= +dfLtTBcBAAAAIgAAAM0BAAAAABcAAAAAAAEAAf/+AgAAAA== +'; + +SELECT * FROM t1; +--echo # Their values should be OFF +SHOW SESSION VARIABLES LIKE "%_checks"; + +--echo # INSERT INTO t1 VALUES(2) +--echo # foreign_key_checks=1 and unique_checks=1 +--echo # It should not change current session's variables, even error happens +--error 1062 +BINLOG ' +dfLtTBMBAAAAKQAAAKsBAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE= +dfLtTBcBAAAAIgAAAM0BAAAAABcAAAAAAAEAAf/+AgAAAA== +'; + +SELECT * FROM t1; +--echo # Their values should be OFF +SHOW SESSION VARIABLES LIKE "%_checks"; + +DROP TABLE t1; + disconnect fresh; diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index d612e7adde1..1678f8add58 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -1330,3 +1330,62 @@ Log_name Pos Event_type Server_id End_log_pos Info # # Write_rows 1 # table_id: # flags: STMT_END_F # # Query 1 # COMMIT DROP TABLE t1; + +# BUG#54903 BINLOG statement toggles session variables +# ---------------------------------------------------------------------- +# This test verify that BINLOG statement doesn't change current session's +# variables foreign_key_checks and unique_checks. + +CREATE TABLE t1 (c1 INT KEY); +SET @@SESSION.foreign_key_checks= ON; +SET @@SESSION.unique_checks= ON; +# INSERT INTO t1 VALUES (1) +# foreign_key_checks=0 and unique_checks=0 +BINLOG ' +dfLtTBMBAAAAKQAAANcAAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE= +dfLtTBcBAAAAIgAAAPkAAAAAABcAAAAAAAcAAf/+AQAAAA== +'; +SELECT * FROM t1; +c1 +1 +# Their values should be ON +SHOW SESSION VARIABLES LIKE "%_checks"; +Variable_name Value +foreign_key_checks ON +unique_checks ON + +SET @@SESSION.foreign_key_checks= OFF; +SET @@SESSION.unique_checks= OFF; +# INSERT INTO t1 VALUES(2) +# foreign_key_checks=1 and unique_checks=1 +BINLOG ' +dfLtTBMBAAAAKQAAAKsBAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE= +dfLtTBcBAAAAIgAAAM0BAAAAABcAAAAAAAEAAf/+AgAAAA== +'; +SELECT * FROM t1; +c1 +1 +2 +# Their values should be OFF +SHOW SESSION VARIABLES LIKE "%_checks"; +Variable_name Value +foreign_key_checks OFF +unique_checks OFF +# INSERT INTO t1 VALUES(2) +# foreign_key_checks=1 and unique_checks=1 +# It should not change current session's variables, even error happens +BINLOG ' +dfLtTBMBAAAAKQAAAKsBAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE= +dfLtTBcBAAAAIgAAAM0BAAAAABcAAAAAAAEAAf/+AgAAAA== +'; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +SELECT * FROM t1; +c1 +1 +2 +# Their values should be OFF +SHOW SESSION VARIABLES LIKE "%_checks"; +Variable_name Value +foreign_key_checks OFF +unique_checks OFF +DROP TABLE t1; diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index f5ba4524c61..872a93bef43 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -801,3 +801,62 @@ Log_name Pos Event_type Server_id End_log_pos Info # # Write_rows 1 # table_id: # flags: STMT_END_F # # Query 1 # COMMIT DROP TABLE t1; + +# BUG#54903 BINLOG statement toggles session variables +# ---------------------------------------------------------------------- +# This test verify that BINLOG statement doesn't change current session's +# variables foreign_key_checks and unique_checks. + +CREATE TABLE t1 (c1 INT KEY); +SET @@SESSION.foreign_key_checks= ON; +SET @@SESSION.unique_checks= ON; +# INSERT INTO t1 VALUES (1) +# foreign_key_checks=0 and unique_checks=0 +BINLOG ' +dfLtTBMBAAAAKQAAANcAAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE= +dfLtTBcBAAAAIgAAAPkAAAAAABcAAAAAAAcAAf/+AQAAAA== +'; +SELECT * FROM t1; +c1 +1 +# Their values should be ON +SHOW SESSION VARIABLES LIKE "%_checks"; +Variable_name Value +foreign_key_checks ON +unique_checks ON + +SET @@SESSION.foreign_key_checks= OFF; +SET @@SESSION.unique_checks= OFF; +# INSERT INTO t1 VALUES(2) +# foreign_key_checks=1 and unique_checks=1 +BINLOG ' +dfLtTBMBAAAAKQAAAKsBAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE= +dfLtTBcBAAAAIgAAAM0BAAAAABcAAAAAAAEAAf/+AgAAAA== +'; +SELECT * FROM t1; +c1 +1 +2 +# Their values should be OFF +SHOW SESSION VARIABLES LIKE "%_checks"; +Variable_name Value +foreign_key_checks OFF +unique_checks OFF +# INSERT INTO t1 VALUES(2) +# foreign_key_checks=1 and unique_checks=1 +# It should not change current session's variables, even error happens +BINLOG ' +dfLtTBMBAAAAKQAAAKsBAAAAABcAAAAAAAEABHRlc3QAAnQxAAEDAAE= +dfLtTBcBAAAAIgAAAM0BAAAAABcAAAAAAAEAAf/+AgAAAA== +'; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +SELECT * FROM t1; +c1 +1 +2 +# Their values should be OFF +SHOW SESSION VARIABLES LIKE "%_checks"; +Variable_name Value +foreign_key_checks OFF +unique_checks OFF +DROP TABLE t1; diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 82de6feb1a9..31fd2de3722 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -50,6 +50,13 @@ void mysql_client_binlog_statement(THD* thd) } size_t decoded_len= base64_needed_decoded_length(coded_len); + /* + thd->options will be changed when applying the event. But we don't expect + it be changed permanently after BINLOG statement, so backup it first. + It will be restored at the end of this function. + */ + ulonglong thd_options= thd->options; + /* Allocation */ @@ -236,6 +243,7 @@ void mysql_client_binlog_statement(THD* thd) my_ok(thd); end: + thd->options= thd_options; rli->clear_tables_to_lock(); my_free(buf, MYF(MY_ALLOW_ZERO_PTR)); DBUG_VOID_RETURN; From 08db5f7eb6071171aa88c86fad8fb89e6595123b Mon Sep 17 00:00:00 2001 From: Date: Mon, 29 Nov 2010 11:04:16 +0800 Subject: [PATCH 033/110] Bug #57666 Unclear warning with broken text in error log on INSERT DELAYED It is not necessary to support INSERT DELAYED for a single value insert, while we do not support that for multi-values insert when binlog is enabled in SBR. The lock_type is upgrade to TL_WRITE from TL_WRITE_DELAYED for INSERT DELAYED for single value insert as multi-values insert did when binlog is enabled. Then it's safe. And binlog it as INSERT without DELAYED. --- .../binlog_tests/binlog_insert_delayed.test | 4 +- .../suite/binlog/r/binlog_row_binlog.result | 4 +- .../r/binlog_statement_insert_delayed.result | 10 +-- .../suite/binlog/r/binlog_stm_binlog.result | 4 +- .../suite/rpl/r/rpl_stm_insert_delayed.result | 8 +- sql/sql_insert.cc | 78 ++++--------------- 6 files changed, 31 insertions(+), 77 deletions(-) diff --git a/mysql-test/extra/binlog_tests/binlog_insert_delayed.test b/mysql-test/extra/binlog_tests/binlog_insert_delayed.test index 2526b2dd149..7b31a3ebf17 100644 --- a/mysql-test/extra/binlog_tests/binlog_insert_delayed.test +++ b/mysql-test/extra/binlog_tests/binlog_insert_delayed.test @@ -34,11 +34,11 @@ create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; let $table=t1; let $count=0; -insert delayed into t1 values (207); +insert /* before delayed */ delayed /* after delayed */ into t1 values (207); inc $count; --source include/wait_until_rows_count.inc -insert delayed into t1 values (null); +insert /*! delayed */ into t1 values (null); inc $count; --source include/wait_until_rows_count.inc diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index b4795e4a0a4..abb02164d91 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -1218,8 +1218,8 @@ master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT drop table t1,t2,t3,tt1; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; -insert delayed into t1 values (207); -insert delayed into t1 values (null); +insert /* before delayed */ delayed /* after delayed */ into t1 values (207); +insert /*! delayed */ into t1 values (null); insert delayed into t1 values (300); FLUSH TABLES; show binlog events from ; diff --git a/mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result b/mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result index 2219961aca0..cdcc96b94b0 100644 --- a/mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result +++ b/mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result @@ -1,6 +1,6 @@ create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; -insert delayed into t1 values (207); -insert delayed into t1 values (null); +insert /* before delayed */ delayed /* after delayed */ into t1 values (207); +insert /*! delayed */ into t1 values (null); insert delayed into t1 values (300); FLUSH TABLES; show binlog events from ; @@ -10,14 +10,14 @@ master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; insert delayed into t1 values (207) +master-bin.000001 # Query # # use `test`; insert /* before delayed */ /* after delayed */ into t1 values (207) master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # BEGIN master-bin.000001 # Intvar # # INSERT_ID=208 -master-bin.000001 # Query # # use `test`; insert delayed into t1 values (null) +master-bin.000001 # Query # # use `test`; insert /*! */ into t1 values (null) master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; insert delayed into t1 values (300) +master-bin.000001 # Query # # use `test`; insert into t1 values (300) master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; FLUSH TABLES RESET MASTER; diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index 2fc399a3370..5960952e22e 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -717,8 +717,8 @@ master-bin.000001 # Query # # use `mysql`; DELETE FROM user WHERE host='localhos master-bin.000001 # Query # # COMMIT drop table t1,t2,t3,tt1; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; -insert delayed into t1 values (207); -insert delayed into t1 values (null); +insert /* before delayed */ delayed /* after delayed */ into t1 values (207); +insert /*! delayed */ into t1 values (null); insert delayed into t1 values (300); FLUSH TABLES; show binlog events from ; diff --git a/mysql-test/suite/rpl/r/rpl_stm_insert_delayed.result b/mysql-test/suite/rpl/r/rpl_stm_insert_delayed.result index 6b0c1c38c16..14ba6080ec0 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_insert_delayed.result +++ b/mysql-test/suite/rpl/r/rpl_stm_insert_delayed.result @@ -51,8 +51,8 @@ CREATE TABLE t1(a int, UNIQUE(a)); INSERT DELAYED IGNORE INTO t1 VALUES(1); INSERT DELAYED IGNORE INTO t1 VALUES(1); flush table t1; -use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1) -use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1) +use `test`; INSERT IGNORE INTO t1 VALUES(1) +use `test`; INSERT IGNORE INTO t1 VALUES(1) select * from t1; a 1 @@ -60,10 +60,10 @@ On slave show binlog events in 'slave-bin.000002' from limit 1,6; Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000002 # Query # # BEGIN -slave-bin.000002 # Query # # use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1) +slave-bin.000002 # Query # # use `test`; INSERT IGNORE INTO t1 VALUES(1) slave-bin.000002 # Query # # COMMIT slave-bin.000002 # Query # # BEGIN -slave-bin.000002 # Query # # use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1) +slave-bin.000002 # Query # # use `test`; INSERT IGNORE INTO t1 VALUES(1) slave-bin.000002 # Query # # COMMIT select * from t1; a diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index bd2aa70806a..0b463ff1202 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -420,8 +420,7 @@ void prepare_triggers_for_insert_stmt(TABLE *table) static void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, - enum_duplicates duplic, - bool is_multi_insert) + enum_duplicates duplic) { if (duplic == DUP_UPDATE || (duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT)) @@ -470,10 +469,9 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, return; } - bool log_on= (thd->variables.option_bits & OPTION_BIN_LOG || - ! (thd->security_ctx->master_access & SUPER_ACL)); + bool log_on= (thd->variables.option_bits & OPTION_BIN_LOG); if (global_system_variables.binlog_format == BINLOG_FORMAT_STMT && - log_on && mysql_bin_log.is_open() && is_multi_insert) + log_on && mysql_bin_log.is_open()) { /* Statement-based binary logging does not work in this case, because: @@ -677,8 +675,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, By default, both logs are enabled (this won't cause problems if the server runs without --log-bin). */ - bool log_on= ((thd->variables.option_bits & OPTION_BIN_LOG) || - (!(thd->security_ctx->master_access & SUPER_ACL))); + bool log_on= (thd->variables.option_bits & OPTION_BIN_LOG); #endif thr_lock_type lock_type; Item *unused_conds= 0; @@ -688,8 +685,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, Upgrade lock type if the requested lock is incompatible with the current connection mode or table operation. */ - upgrade_lock_type(thd, &table_list->lock_type, duplic, - values_list.elements > 1); + upgrade_lock_type(thd, &table_list->lock_type, duplic); /* We can't write-delayed into a table locked with LOCK TABLES: @@ -1022,7 +1018,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0); if (was_insert_delayed && table_list->lock_type == TL_WRITE) { - /* Binlog multi INSERT DELAYED as INSERT without DELAYED. */ + /* Binlog INSERT DELAYED as INSERT without DELAYED. */ String log_query; if (create_insert_stmt_from_insert_delayed(thd, &log_query)) { @@ -1905,22 +1901,6 @@ public: thd.command=COM_DELAYED_INSERT; thd.lex->current_select= 0; // for my_message_sql thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock() - /* - Statement-based replication of INSERT DELAYED has problems with - RAND() and user variables, so in mixed mode we go to row-based. - For normal commands, the unsafe flag is set at parse time. - However, since the flag is a member of the THD object, of which - the delayed_insert thread has its own copy, we must set the - statement to unsafe here and explicitly set row logging mode. - - @todo set_current_stmt_binlog_format_row_if_mixed should not be - called by anything else than thd->decide_logging_format(). When - we call set_current_blah here, none of the checks in - decide_logging_format is made. We should probably call - thd->decide_logging_format() directly instead. /Sven - */ - thd.lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_DELAYED); - thd.set_current_stmt_binlog_format_row_if_mixed(); /* Prevent changes to global.lock_wait_timeout from affecting delayed insert threads as any timeouts in delayed inserts @@ -2650,11 +2630,11 @@ pthread_handler_t handle_delayed_insert(void *arg) } thd->lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock() + /* - Statement-based replication of INSERT DELAYED has problems with RAND() - and user vars, so in mixed mode we go to row-based. + INSERT DELAYED has to go to row-based format because the time + at which rows are inserted cannot be determined in mixed mode. */ - thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_DELAYED); thd->set_current_stmt_binlog_format_row_if_mixed(); /* @@ -2921,6 +2901,13 @@ bool Delayed_insert::handle_inserts(void) (ulong) row->query.length)); if (log_query) { + /* + Guaranteed that the INSERT DELAYED STMT will not be here + in SBR when mysql binlog is enabled. + */ + DBUG_ASSERT(!(mysql_bin_log.is_open() && + !thd.is_current_stmt_binlog_format_row())); + /* This is the first value of an INSERT statement. It is the right place to clear a forced insert_id. @@ -2988,39 +2975,6 @@ bool Delayed_insert::handle_inserts(void) table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); } - if (log_query && mysql_bin_log.is_open()) - { - bool backup_time_zone_used = thd.time_zone_used; - Time_zone *backup_time_zone = thd.variables.time_zone; - if (row->time_zone != NULL) - { - thd.time_zone_used = true; - thd.variables.time_zone = row->time_zone; - } - - /* if the delayed insert was killed, the killed status is - ignored while binlogging */ - int errcode= 0; - if (thd.killed == THD::NOT_KILLED) - errcode= query_error_code(&thd, TRUE); - - /* - If the query has several rows to insert, only the first row will come - here. In row-based binlogging, this means that the first row will be - written to binlog as one Table_map event and one Rows event (due to an - event flush done in binlog_query()), then all other rows of this query - will be binlogged together as one single Table_map event and one - single Rows event. - */ - if (thd.binlog_query(THD::ROW_QUERY_TYPE, - row->query.str, row->query.length, - FALSE, FALSE, FALSE, errcode)) - goto err; - - thd.time_zone_used = backup_time_zone_used; - thd.variables.time_zone = backup_time_zone; - } - if (table->s->blob_fields) free_delayed_insert_blobs(table); thread_safe_decrement(delayed_rows_in_use,&LOCK_delayed_status); From 12c5a7d72fef027dcfe348ac3c3bdcb85892c921 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 29 Nov 2010 17:30:07 +0200 Subject: [PATCH 034/110] Fixed a pb2 issue with not finding the test dirs. --- mysql-test/collections/default.push | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/collections/default.push b/mysql-test/collections/default.push index 0f4115c8565..ce7b491efe7 100644 --- a/mysql-test/collections/default.push +++ b/mysql-test/collections/default.push @@ -1,2 +1,2 @@ -perl mysql-test-run.pl --timer --force --comment=n_stm -perl mysql-test-run.pl --timer --force --comment=ps_stm --ps-protocol +perl mysql-test-run.pl --timer --force --vardir=n_stm --comment=n_stm +perl mysql-test-run.pl --timer --force --vardir=ps_stm --comment=ps_stm --ps-protocol From 24800599b3ebca0c0d71ea5446fe140ae81745ff Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 29 Nov 2010 17:33:24 +0200 Subject: [PATCH 035/110] Fixed bteam issue #37235: 5.0 trees now will work correctly in pb2 and will not display "indicated result file not found" due to wrongly named var directory. --- mysql-test/collections/default.push | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/collections/default.push b/mysql-test/collections/default.push index ce7b491efe7..638918d1026 100644 --- a/mysql-test/collections/default.push +++ b/mysql-test/collections/default.push @@ -1,2 +1,2 @@ -perl mysql-test-run.pl --timer --force --vardir=n_stm --comment=n_stm -perl mysql-test-run.pl --timer --force --vardir=ps_stm --comment=ps_stm --ps-protocol +perl mysql-test-run.pl --timer --force --vardir=var-n_stm --comment=n_stm +perl mysql-test-run.pl --timer --force --vardir=var-ps_stm --comment=ps_stm --ps-protocol From 33b560e89d181de19c22e60dff0cf7f5fe7fc2ea Mon Sep 17 00:00:00 2001 From: Christopher Powers Date: Mon, 29 Nov 2010 18:51:46 -0600 Subject: [PATCH 036/110] Bug#35333, "If Federated table can't connect to remote host, can't retrieve metadata" Improved error handling such that queries against Information_Schema.Tables won't fail if a Federated table is unable to connect to remote host. --- mysql-test/r/federated_bug_35333.result | 76 ++++++++ mysql-test/r/information_schema.result | 2 + mysql-test/r/information_schema_db.result | 4 + mysql-test/r/show_check.result | 2 + mysql-test/r/view.result | 2 + mysql-test/t/federated_bug_35333.test | 74 ++++++++ sql/sql_show.cc | 200 ++++++++++++---------- 7 files changed, 273 insertions(+), 87 deletions(-) create mode 100644 mysql-test/r/federated_bug_35333.result create mode 100644 mysql-test/t/federated_bug_35333.test diff --git a/mysql-test/r/federated_bug_35333.result b/mysql-test/r/federated_bug_35333.result new file mode 100644 index 00000000000..964fedc3205 --- /dev/null +++ b/mysql-test/r/federated_bug_35333.result @@ -0,0 +1,76 @@ +# +# Bug 35333 "If a Federated table can't connect to the remote hose, can't retrieve metadata" +# +# Queries such as SHOW TABLE STATUS and SELECT * FROM INFORMATION_SCHEMA.TABLES fail +# when encountering a federated table that cannot connect to its remote table. +# +# The fix is to store the error text in the TABLE COMMENTS column of I_S.TABLES, clear +# the remote connection error and push a warning instead. This allows the SELECT operation +# to complete while still indicating a problem. This fix applies to any non-fatal system +# error that occurs during a query against I_S.TABLES.de +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; +stop slave; +DROP DATABASE IF EXISTS federated; +CREATE DATABASE federated; +DROP DATABASE IF EXISTS federated; +CREATE DATABASE federated; +CREATE DATABASE IF NOT EXISTS realdb; +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +# +# Create the base table to be referenced +# +CREATE TABLE realdb.t0 (a text, b text) ENGINE=MYISAM; +# +# Create a federated table with a bogus port number +# +CREATE TABLE federated.t0 (a text, b text) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:63333/realdb/t0'; +# +# Trigger a federated system error during a INFORMATION_SCHEMA.TABLES query +# +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT +FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'realdb' or TABLE_SCHEMA = 'federated'; +TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE ROW_FORMAT TABLE_ROWS DATA_LENGTH TABLE_COMMENT +federated t0 NULL NULL NULL NULL Unable to connect to foreign data source: Can't connect to MySQL server on '127. +realdb t0 BASE TABLE MyISAM Dynamic 0 0 +Warnings: +Warning 1429 Unable to connect to foreign data source: Can't connect to MySQL server on '127.0.0.1' (socket errno) +SHOW WARNINGS; +Level Code Message +Warning 1429 Unable to connect to foreign data source: Can't connect to MySQL server on '127.0.0.1' (socket errno) +# +# Create a MyISAM table then corrupt the file +# +USE realdb; +CREATE TABLE t1 (c1 int) ENGINE=MYISAM; +# +# Corrupt the MyISAM table by deleting the base file +# +# +# Trigger a MyISAM system error during an INFORMATION_SCHEMA.TABLES query +# +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT +FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE ROW_FORMAT TABLE_ROWS DATA_LENGTH TABLE_COMMENT +realdb t1 BASE TABLE NULL NULL NULL NULL Can't find file: 't1' (errno: 2) +Warnings: +Warning 1017 Can't find file: 't1' (errno: 2) +SHOW WARNINGS; +Level Code Message +Warning 1017 Can't find file: 't1' (errno: 2) +# +# Cleanup +# +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +DROP DATABASE realdb; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 54fa4be027e..9c3d9e09bad 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1053,6 +1053,8 @@ select table_type from information_schema.tables where table_name="v1"; table_type VIEW +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 drop view v1; create temporary table t1(f1 int, index(f1)); show columns from t1; diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index 92c5b6de2ec..552114849c4 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -65,10 +65,14 @@ select table_name, table_type, table_comment from information_schema.tables where table_schema='inf%' and func2(); table_name table_type table_comment v1 VIEW View 'inf%.v1' references invalid table(s) or column(s) or function(s) or define +Warnings: +Warning 1356 View 'inf%.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them select table_name, table_type, table_comment from information_schema.tables where table_schema='inf%' and func2(); table_name table_type table_comment v1 VIEW View 'inf%.v1' references invalid table(s) or column(s) or function(s) or define +Warnings: +Warning 1356 View 'inf%.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them drop view v1; drop function func1; drop function func2; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index ad73fc650a5..2d9565ac54d 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -622,6 +622,8 @@ flush tables; SHOW TABLE STATUS like 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect information in file: './test/t1.frm' +Warnings: +Warning 1033 Incorrect information in file: './test/t1.frm' show create table t1; ERROR HY000: Incorrect information in file: './test/t1.frm' drop table t1; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 715fb225550..d98ef86b7c3 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -840,6 +840,8 @@ show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL View 'test.v1' references invalid table(s) or column(s) or function(s) or define +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 drop view v1; drop table t1; create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1; diff --git a/mysql-test/t/federated_bug_35333.test b/mysql-test/t/federated_bug_35333.test new file mode 100644 index 00000000000..e04e719827e --- /dev/null +++ b/mysql-test/t/federated_bug_35333.test @@ -0,0 +1,74 @@ +--echo # +--echo # Bug 35333 "If a Federated table can't connect to the remote hose, can't retrieve metadata" +--echo # +--echo # Queries such as SHOW TABLE STATUS and SELECT * FROM INFORMATION_SCHEMA.TABLES fail +--echo # when encountering a federated table that cannot connect to its remote table. +--echo # +--echo # The fix is to store the error text in the TABLE COMMENTS column of I_S.TABLES, clear +--echo # the remote connection error and push a warning instead. This allows the SELECT operation +--echo # to complete while still indicating a problem. This fix applies to any non-fatal system +--echo # error that occurs during a query against I_S.TABLES.de + +--source include/federated.inc + +--disable_warnings +CREATE DATABASE IF NOT EXISTS realdb; +# Federated database exists +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +--enable_warnings + +--echo # +--echo # Create the base table to be referenced +--echo # +CREATE TABLE realdb.t0 (a text, b text) ENGINE=MYISAM; + +--echo # +--echo # Create a federated table with a bogus port number +--echo # +CREATE TABLE federated.t0 (a text, b text) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:63333/realdb/t0'; + +#--warning ER_CONNECT_TO_FOREIGN_DATA_SOURCE + +--echo # +--echo # Trigger a federated system error during a INFORMATION_SCHEMA.TABLES query +--echo # +# Remove O/S-specific socket error +--replace_regex /\(.*\)/(socket errno)/ +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT + FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'realdb' or TABLE_SCHEMA = 'federated'; + +# Remove O/S-specific socket error +--replace_regex /\(.*\)/(socket errno)/ +SHOW WARNINGS; + +--echo # +--echo # Create a MyISAM table then corrupt the file +--echo # +USE realdb; +CREATE TABLE t1 (c1 int) ENGINE=MYISAM; +--echo # +--echo # Corrupt the MyISAM table by deleting the base file +--echo # +let $MYSQLD_DATADIR= `SELECT @@datadir`; +--remove_file $MYSQLD_DATADIR/realdb/t1.MYD +--remove_file $MYSQLD_DATADIR/realdb/t1.MYI + +--echo # +--echo # Trigger a MyISAM system error during an INFORMATION_SCHEMA.TABLES query +--echo # +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT + FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; + +SHOW WARNINGS; +--echo # +--echo # Cleanup +--echo # +--disable_warnings +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +DROP DATABASE realdb; +--enable_warnings + +--source include/federated_cleanup.inc diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 13045280c5f..1075e7f76d1 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -48,7 +48,7 @@ bool schema_table_store_record(THD *thd, TABLE *table); /*************************************************************************** -** List all table types supported +** List all table types supported ***************************************************************************/ bool mysqld_show_storage_engines(THD *thd) @@ -65,7 +65,7 @@ bool mysqld_show_storage_engines(THD *thd) Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) DBUG_RETURN(TRUE); - const char *default_type_name= + const char *default_type_name= ha_get_storage_engine((enum db_type)thd->variables.table_type); handlerton **types; @@ -406,7 +406,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) /* Clear all messages with 'error' level status and - issue a warning with 'warning' level status in + issue a warning with 'warning' level status in case of invalid view and last error is ER_VIEW_INVALID */ mysql_reset_errors(thd, true); @@ -603,7 +603,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) Field **ptr,*field; for (ptr=table->field ; (field= *ptr); ptr++) { - if (!wild || !wild[0] || + if (!wild || !wild[0] || !wild_case_compare(system_charset_info, field->field_name,wild)) { if (table_list->view) @@ -809,13 +809,13 @@ static bool get_field_default_value(THD *thd, TABLE *table, bool has_default; bool has_now_default; enum enum_field_types field_type= field->type(); - /* + /* We are using CURRENT_TIMESTAMP instead of NOW because it is more standard */ - has_now_default= table->timestamp_field == field && + has_now_default= table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_UN_FIELD; - + has_default= (field_type != FIELD_TYPE_BLOB && !(field->flags & NO_DEFAULT_VALUE_FLAG) && field->unireg_check != Field::NEXT_NUMBER && @@ -837,7 +837,7 @@ static bool get_field_default_value(THD *thd, TABLE *table, char *ptr= longlong2str(dec, tmp + 2, 2); uint32 length= (uint32) (ptr - tmp); tmp[0]= 'b'; - tmp[1]= '\''; + tmp[1]= '\''; tmp[length]= '\''; type.length(length + 1); quoted= 0; @@ -929,7 +929,7 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) field->sql_type(type); packet->append(type.ptr(), type.length(), system_charset_info); - if (field->has_charset() && + if (field->has_charset() && !(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))) { if (field->charset() != share->table_charset) @@ -937,8 +937,8 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) packet->append(STRING_WITH_LEN(" character set ")); packet->append(field->charset()->csname); } - /* - For string types dump collation name only if + /* + For string types dump collation name only if collation is not primary for the given charset */ if (!(field->charset()->state & MY_CS_PRIMARY)) @@ -965,11 +965,11 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) packet->append(def_value.ptr(), def_value.length(), system_charset_info); } - if (!limited_mysql_mode && table->timestamp_field == field && + if (!limited_mysql_mode && table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD) packet->append(STRING_WITH_LEN(" on update CURRENT_TIMESTAMP")); - if (field->unireg_check == Field::NEXT_NUMBER && + if (field->unireg_check == Field::NEXT_NUMBER && !(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS)) packet->append(STRING_WITH_LEN(" auto_increment")); @@ -1088,7 +1088,7 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) packet->append(buff, (uint) (end - buff)); } - + if (share->table_charset && !(thd->variables.sql_mode & MODE_MYSQL323) && !(thd->variables.sql_mode & MODE_MYSQL40)) @@ -1179,7 +1179,7 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff) /* Append DEFINER clause to the given buffer. - + SYNOPSIS append_definer() thd [in] thread handle @@ -1209,7 +1209,7 @@ static void append_algorithm(TABLE_LIST *table, String *buff) /* Append DEFINER clause to the given buffer. - + SYNOPSIS append_definer() thd [in] thread handle @@ -1374,8 +1374,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) "%s:%u", tmp_sctx->host_or_ip, tmp->peer_port); } else - thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ? - tmp_sctx->host_or_ip : + thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ? + tmp_sctx->host_or_ip : tmp_sctx->host ? tmp_sctx->host : ""); if ((thd_info->db=tmp->db)) // Safe test thd_info->db=thd->strdup(thd_info->db); @@ -1852,14 +1852,14 @@ void calc_sum_of_all_status(STATUS_VAR *to) I_List_iterator it(threads); THD *tmp; - + /* Get global values as base */ *to= global_status_var; - + /* Add to this status from existing threads */ while ((tmp= it++)) add_to_status(to, &tmp->status_var); - + VOID(pthread_mutex_unlock(&LOCK_thread_count)); DBUG_VOID_RETURN; } @@ -1911,7 +1911,7 @@ bool schema_table_store_record(THD *thd, TABLE *table) int error; if ((error= table->file->write_row(table->record[0]))) { - if (create_myisam_from_heap(thd, table, + if (create_myisam_from_heap(thd, table, table->pos_in_table_list->schema_table_param, error, 0)) return 1; @@ -1946,7 +1946,7 @@ int make_table_list(THD *thd, SELECT_LEX *sel, { Table_ident *table_ident; LEX_STRING ident_db, ident_table; - ident_db.str= db; + ident_db.str= db; ident_db.length= (uint) strlen(db); ident_table.str= table; ident_table.length= (uint) strlen(table); @@ -1980,10 +1980,10 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table) const char *field_name2= schema_table->idx_field2 >= 0 ? field_info[schema_table->idx_field2].field_name : ""; if (table->table != item_field->field->table || (cs->coll->strnncollsp(cs, (uchar *) field_name1, (uint) strlen(field_name1), - (uchar *) item_field->field_name, + (uchar *) item_field->field_name, (uint) strlen(item_field->field_name), 0) && cs->coll->strnncollsp(cs, (uchar *) field_name2, (uint) strlen(field_name2), - (uchar *) item_field->field_name, + (uchar *) item_field->field_name, (uint) strlen(item_field->field_name), 0))) return 0; } @@ -2072,7 +2072,7 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table) with_i_schema returns 1 if we added 'IS' name to list otherwise returns 0 is_wild_value if value is 1 then idx_field_vals->db_name is - wild string otherwise it's db name; + wild string otherwise it's db name; RETURN zero success @@ -2094,7 +2094,7 @@ int make_db_list(THD *thd, List *files, LIKE clause (see also get_index_field_values() function) */ if (!idx_field_vals->db_value || - !wild_case_compare(system_charset_info, + !wild_case_compare(system_charset_info, INFORMATION_SCHEMA_NAME.str, idx_field_vals->db_value)) { @@ -2179,7 +2179,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) List bases; List_iterator_fast it(bases); COND *partial_cond; - uint derived_tables= lex->derived_tables; + uint derived_tables= lex->derived_tables; int error= 1; db_type not_used; Open_tables_state open_tables_state_backup; @@ -2217,7 +2217,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) Let us set fake sql_command so views won't try to merge themselves into main statement. If we don't do this, SELECT * from information_schema.xxxx will cause problems. - SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' + SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' */ lex->sql_command= SQLCOM_SHOW_FIELDS; res= open_normal_and_derived_tables(thd, show_table_list, @@ -2227,15 +2227,15 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) get_all_tables() returns 1 on failure and 0 on success thus return only these and not the result code of ::process_table() - We should use show_table_list->alias instead of + We should use show_table_list->alias instead of show_table_list->table_name because table_name could be changed during opening of I_S tables. It's safe - to use alias because alias contains original table name - in this case(this part of code is used only for + to use alias because alias contains original table name + in this case(this part of code is used only for 'show columns' & 'show statistics' commands). */ error= test(schema_table->process_table(thd, show_table_list, - table, res, + table, res, (show_table_list->view ? show_table_list->view_db.str : show_table_list->db), @@ -2263,7 +2263,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) (base_name= select_lex->db) && !bases.elements)) { #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (!check_access(thd,SELECT_ACL, base_name, + if (!check_access(thd,SELECT_ACL, base_name, &thd->col_access, 0, 1, with_i_schema) || sctx->master_access & (DB_ACLS | SHOW_DB_ACL) || acl_get(sctx->host, sctx->ip, sctx->priv_user, base_name,0) || @@ -2281,7 +2281,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) strxmov(path, mysql_data_home, "/", base_name, NullS); end= path + (len= unpack_dirname(path,path)); len= FN_LEN - len; - find_files_result res= find_files(thd, &files, base_name, + find_files_result res= find_files(thd, &files, base_name, path, idx_field_vals.table_value, 0); if (res != FIND_FILES_OK) { @@ -2367,9 +2367,9 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) res= open_normal_and_derived_tables(thd, show_table_list, MYSQL_LOCK_IGNORE_FLUSH); lex->sql_command= save_sql_command; - /* + /* They can drop table after table names list creation and - before table opening. We open non existing table and + before table opening. We open non existing table and get ER_NO_SUCH_TABLE error. In this case we do not store the record into I_S table and clear error. */ @@ -2381,10 +2381,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) else { /* - We should use show_table_list->alias instead of + We should use show_table_list->alias instead of show_table_list->table_name because table_name could be changed during opening of I_S tables. It's safe - to use alias because alias contains original table name + to use alias because alias contains original table name in this case. */ res= schema_table->process_table(thd, show_table_list, table, @@ -2486,28 +2486,28 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, { const char *tmp_buff; MYSQL_TIME time; + int info_error= 0; CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_tables_record"); restore_record(table, s->default_values); table->field[1]->store(base_name, (uint) strlen(base_name), cs); table->field[2]->store(file_name, (uint) strlen(file_name), cs); + if (res) { - /* - there was errors during opening tables - */ - const char *error= thd->net.last_error; + /* There was a table open error, so set the table type and return */ if (tables->view) table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); else if (tables->schema_table) table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs); else table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs); - table->field[20]->store(error, (uint) strlen(error), cs); - thd->clear_error(); + + goto err; } - else if (tables->view) + + if (tables->view) { table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); table->field[20]->store(STRING_WITH_LEN("VIEW"), cs); @@ -2518,8 +2518,15 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, TABLE_SHARE *share= show_table->s; handler *file= show_table->file; - file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO | - HA_STATUS_NO_LOCK); + if (!file) + goto err; + + if ((info_error= file->info(HA_STATUS_VARIABLE | + HA_STATUS_TIME | + HA_STATUS_AUTO | + HA_STATUS_NO_LOCK)) != 0) + goto err; + if (share->tmp_table == SYSTEM_TMP_TABLE) table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs); else if (share->tmp_table) @@ -2636,7 +2643,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE) ptr=strmov(ptr," delay_key_write=1"); if (share->row_type != ROW_TYPE_DEFAULT) - ptr=strxmov(ptr, " row_format=", + ptr=strxmov(ptr, " row_format=", ha_row_type[(uint) share->row_type], NullS); if (file->raid_type) @@ -2649,7 +2656,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, ptr=strmov(ptr,buff); } table->field[19]->store(option_buff+1, - (ptr == option_buff ? 0 : + (ptr == option_buff ? 0 : (uint) (ptr-option_buff)-1), cs); { char *comment; @@ -2658,13 +2665,32 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, { table->field[20]->store(comment, (comment == share->comment.str ? - share->comment.length : + share->comment.length : (uint) strlen(comment)), cs); if (comment != share->comment.str) my_free(comment, MYF(0)); } } } + +err: + if (res || info_error) + { + /* + If an error was encountered, push a warning, set the TABLE COMMENT + column with the error text, and clear the error so that the operation + can continue. + */ + const char *error= thd->net.last_error; + if (error) + { + table->field[20]->store(error, strlen(error), cs); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + thd->net.last_errno, thd->net.last_error); + thd->clear_error(); + } + } + DBUG_RETURN(schema_table_store_record(thd, table)); } @@ -2691,7 +2717,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, /* I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS rather than in SHOW COLUMNS - */ + */ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->net.last_errno, thd->net.last_error); thd->clear_error(); @@ -2732,7 +2758,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, uint col_access; check_access(thd,SELECT_ACL | EXTRA_ACL, base_name, &tables->grant.privilege, 0, 0, test(tables->schema_table)); - col_access= get_column_grant(thd, &tables->grant, + col_access= get_column_grant(thd, &tables->grant, base_name, file_name, field->field_name) & COL_ACLS; if (!tables->schema_table && !col_access) @@ -2755,9 +2781,9 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, cs); table->field[4]->store((longlong) count, TRUE); field->sql_type(type); - table->field[14]->store(type.ptr(), type.length(), cs); + table->field[14]->store(type.ptr(), type.length(), cs); tmp_buff= strchr(type.ptr(), '('); - table->field[7]->store(type.ptr(), (uint) + table->field[7]->store(type.ptr(), (uint) (tmp_buff ? tmp_buff - type.ptr() : type.length()), cs); @@ -2778,7 +2804,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, uint32 octet_max_length= field->max_display_length(); if (is_blob && octet_max_length != (uint32) 4294967295U) octet_max_length /= field->charset()->mbmaxlen; - longlong char_max_len= is_blob ? + longlong char_max_len= is_blob ? (longlong) octet_max_length / field->charset()->mbminlen : (longlong) octet_max_length / field->charset()->mbmaxlen; table->field[8]->store(char_max_len, TRUE); @@ -2811,7 +2837,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, field_length= field->max_display_length(); decimals= -1; // return NULL break; - case FIELD_TYPE_FLOAT: + case FIELD_TYPE_FLOAT: case FIELD_TYPE_DOUBLE: field_length= field->field_length; if (decimals == NOT_FIXED_DEC) @@ -2874,7 +2900,7 @@ int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond) for (cs= all_charsets ; cs < all_charsets+255 ; cs++) { CHARSET_INFO *tmp_cs= cs[0]; - if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) && + if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) && (tmp_cs->state & MY_CS_AVAILABLE) && !(wild && wild[0] && wild_case_compare(scs, tmp_cs->csname,wild))) @@ -2904,13 +2930,13 @@ int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond) { CHARSET_INFO **cl; CHARSET_INFO *tmp_cs= cs[0]; - if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || + if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || !(tmp_cs->state & MY_CS_PRIMARY)) continue; for (cl= all_charsets; cl < all_charsets+255 ;cl ++) { CHARSET_INFO *tmp_cl= cl[0]; - if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || + if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || !my_charset_same(tmp_cs, tmp_cl)) continue; if (!(wild && wild[0] && @@ -2944,13 +2970,13 @@ int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond) { CHARSET_INFO **cl; CHARSET_INFO *tmp_cs= cs[0]; - if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || + if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || !(tmp_cs->state & MY_CS_PRIMARY)) continue; for (cl= all_charsets; cl < all_charsets+255 ;cl ++) { CHARSET_INFO *tmp_cl= cl[0]; - if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || + if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || !my_charset_same(tmp_cs,tmp_cl)) continue; restore_record(table, s->default_values); @@ -3014,7 +3040,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, table->field[10]->store(STRING_WITH_LEN("SQL"), cs); get_field(thd->mem_root, proc_table->field[6], &tmp_string); table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs); - table->field[12]->store(sp_data_access_name[enum_idx].str, + table->field[12]->store(sp_data_access_name[enum_idx].str, sp_data_access_name[enum_idx].length , cs); get_field(thd->mem_root, proc_table->field[7], &tmp_string); table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs); @@ -3290,10 +3316,10 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, if (schema_table_store_record(thd, table)) DBUG_RETURN(1); if (res) - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->net.last_errno, thd->net.last_error); } - if (res) + if (res) thd->clear_error(); DBUG_RETURN(0); } @@ -3334,7 +3360,7 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, TABLE *show_table= tables->table; KEY *key_info=show_table->key_info; uint primary_key= show_table->s->primary_key; - show_table->file->info(HA_STATUS_VARIABLE | + show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); for (uint i=0 ; i < show_table->s->keys ; i++, key_info++) @@ -3363,7 +3389,7 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, List_iterator_fast it(f_key_list); while ((f_key_info=it++)) { - if (store_constraints(thd, table, base_name, file_name, + if (store_constraints(thd, table, base_name, file_name, f_key_info->forein_id->str, (uint) strlen(f_key_info->forein_id->str), "FOREIGN KEY", 11)) @@ -3472,7 +3498,7 @@ ret: void store_key_column_usage(TABLE *table, const char*db, const char *tname, - const char *key_name, uint key_len, + const char *key_name, uint key_len, const char *con_type, uint con_len, longlong idx) { CHARSET_INFO *cs= system_charset_info; @@ -3506,7 +3532,7 @@ static int get_schema_key_column_usage_record(THD *thd, TABLE *show_table= tables->table; KEY *key_info=show_table->key_info; uint primary_key= show_table->s->primary_key; - show_table->file->info(HA_STATUS_VARIABLE | + show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); for (uint i=0 ; i < show_table->s->keys ; i++, key_info++) @@ -3523,8 +3549,8 @@ static int get_schema_key_column_usage_record(THD *thd, restore_record(table, s->default_values); store_key_column_usage(table, base_name, file_name, key_info->name, - (uint) strlen(key_info->name), - key_part->field->field_name, + (uint) strlen(key_info->name), + key_part->field->field_name, (uint) strlen(key_part->field->field_name), (longlong) f_idx); if (schema_table_store_record(thd, table)) @@ -3560,7 +3586,7 @@ static int get_schema_key_column_usage_record(THD *thd, system_charset_info); table->field[9]->set_notnull(); table->field[10]->store(f_key_info->referenced_table->str, - f_key_info->referenced_table->length, + f_key_info->referenced_table->length, system_charset_info); table->field[10]->set_notnull(); table->field[11]->store(r_info->str, r_info->length, @@ -3607,7 +3633,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) LEX *lex= thd->lex; const char *wild= lex->wild ? lex->wild->ptr() : NullS; pthread_mutex_lock(&LOCK_global_system_variables); - res= show_status_array(thd, wild, init_vars, + res= show_status_array(thd, wild, init_vars, lex->option_type, 0, "", tables->table); pthread_mutex_unlock(&LOCK_global_system_variables); DBUG_RETURN(res); @@ -3626,7 +3652,7 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) if (lex->option_type == OPT_GLOBAL) calc_sum_of_all_status(&tmp); res= show_status_array(thd, wild, status_vars, OPT_GLOBAL, - (lex->option_type == OPT_GLOBAL ? + (lex->option_type == OPT_GLOBAL ? &tmp: &thd->status_var), "",tables->table); pthread_mutex_unlock(&LOCK_status); DBUG_RETURN(res); @@ -3717,7 +3743,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) break; case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: - if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC, + if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC, fields_info->field_length)) == NULL) DBUG_RETURN(NULL); break; @@ -3761,7 +3787,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) tmp_table_param->schema_table= 1; SELECT_LEX *select_lex= thd->lex->current_select; if (!(table= create_tmp_table(thd, tmp_table_param, - field_list, (ORDER*) 0, 0, 0, + field_list, (ORDER*) 0, 0, 0, (select_lex->options | thd->options | TMP_TABLE_ALL_COLUMNS), HA_POS_ERROR, table_list->alias))) @@ -4102,7 +4128,7 @@ bool get_schema_tables_result(JOIN *join, thd->no_warnings_for_error= 1; for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++) - { + { if (!tab->table || !tab->table->pos_in_table_list) break; @@ -4454,13 +4480,13 @@ ST_FIELD_INFO variables_fields_info[]= ST_SCHEMA_TABLE schema_tables[]= { - {"CHARACTER_SETS", charsets_fields_info, create_schema_table, + {"CHARACTER_SETS", charsets_fields_info, create_schema_table, fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0}, - {"COLLATIONS", collation_fields_info, create_schema_table, + {"COLLATIONS", collation_fields_info, create_schema_table, fill_schema_collation, make_old_format, 0, -1, -1, 0}, {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info, create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0}, - {"COLUMNS", columns_fields_info, create_schema_table, + {"COLUMNS", columns_fields_info, create_schema_table, get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0}, {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table, fill_schema_column_privileges, 0, 0, -1, -1, 0}, @@ -4469,19 +4495,19 @@ ST_SCHEMA_TABLE schema_tables[]= {"OPEN_TABLES", open_tables_fields_info, create_schema_table, fill_open_tables, make_old_format, 0, -1, -1, 1}, {"PROFILING", query_profile_statistics_info, create_schema_table, - fill_query_profile_statistics_info, make_profile_table_for_show, + fill_query_profile_statistics_info, make_profile_table_for_show, NULL, -1, -1, false}, - {"ROUTINES", proc_fields_info, create_schema_table, + {"ROUTINES", proc_fields_info, create_schema_table, fill_schema_proc, make_proc_old_format, 0, -1, -1, 0}, {"SCHEMATA", schema_fields_info, create_schema_table, fill_schema_shemata, make_schemata_old_format, 0, 1, -1, 0}, {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table, fill_schema_schema_privileges, 0, 0, -1, -1, 0}, - {"STATISTICS", stat_fields_info, create_schema_table, + {"STATISTICS", stat_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0}, - {"STATUS", variables_fields_info, create_schema_table, fill_status, + {"STATUS", variables_fields_info, create_schema_table, fill_status, make_old_format, 0, -1, -1, 1}, - {"TABLES", tables_fields_info, create_schema_table, + {"TABLES", tables_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0}, {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table, get_all_tables, 0, get_schema_constraints_record, 3, 4, 0}, @@ -4491,11 +4517,11 @@ ST_SCHEMA_TABLE schema_tables[]= fill_schema_table_privileges, 0, 0, -1, -1, 0}, {"TRIGGERS", triggers_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0}, - {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, + {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, fill_schema_user_privileges, 0, 0, -1, -1, 0}, {"VARIABLES", variables_fields_info, create_schema_table, fill_variables, make_old_format, 0, -1, -1, 1}, - {"VIEWS", view_fields_info, create_schema_table, + {"VIEWS", view_fields_info, create_schema_table, get_all_tables, 0, get_schema_views_record, 1, 2, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0} }; From f40cc1e000d739046d4044c9198a653993af9ce7 Mon Sep 17 00:00:00 2001 From: Christopher Powers Date: Mon, 29 Nov 2010 22:46:43 -0600 Subject: [PATCH 037/110] Bug#35333, "If Federated table can't connect to remote host, can't retrieve metadata" Improved error handling such that queries against Information_Schema.Tables won't fail if a federated table can't make a remote connection. --- mysql-test/r/merge.result | 2 + mysql-test/r/show_check.result | 16 ++-- mysql-test/r/view.result | 2 + .../federated/federated_bug_35333.result | 67 +++++++++++++++++ .../suite/federated/federated_bug_35333.test | 74 +++++++++++++++++++ sql/sql_show.cc | 43 ++++++++--- 6 files changed, 188 insertions(+), 16 deletions(-) create mode 100644 mysql-test/suite/federated/federated_bug_35333.result create mode 100644 mysql-test/suite/federated/federated_bug_35333.test diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 1fb074d38bf..3af152672ab 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2024,6 +2024,8 @@ SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='tm1'; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT NULL test tm1 BASE TABLE NULL NULL NULL # # # # # # # # # # NULL # # Unable to open underlying table which is differently defined or of non-MyISAM ty +Warnings: +Warning 1168 Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist DROP TABLE tm1; CREATE TABLE t1(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; CREATE TABLE t2(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 08b9211bd31..5f444759346 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -660,6 +660,8 @@ flush tables; SHOW TABLE STATUS like 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect information in file: './test/t1.frm' +Warnings: +Warning 1033 Incorrect information in file: './test/t1.frm' show create table t1; ERROR HY000: Incorrect information in file: './test/t1.frm' drop table if exists t1; @@ -1196,7 +1198,7 @@ set names koi8r; DROP DATABASE IF EXISTS mysqltest1; CREATE DATABASE mysqltest1; use mysqltest1; -CREATE TABLE t1(ËÏÌÏÎËÁ1 INT); +CREATE TABLE t1(�������1 INT); ---> Dumping mysqltest1 to outfile1 @@ -1208,7 +1210,7 @@ DROP DATABASE mysqltest1; SHOW CREATE TABLE mysqltest1.t1; Table Create Table t1 CREATE TABLE `t1` ( - `ËÏÌÏÎËÁ1` int(11) DEFAULT NULL + `�������1` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP DATABASE mysqltest1; use test; @@ -1415,14 +1417,14 @@ DROP PROCEDURE IF EXISTS p1; DROP FUNCTION IF EXISTS f1; DROP TABLE IF EXISTS t1; DROP EVENT IF EXISTS ev1; -CREATE VIEW v1 AS SELECT 'ÔÅÓÔ' AS test; -CREATE PROCEDURE p1() SELECT 'ÔÅÓÔ' AS test; -CREATE FUNCTION f1() RETURNS CHAR(10) RETURN 'ÔÅÓÔ'; +CREATE VIEW v1 AS SELECT '����' AS test; +CREATE PROCEDURE p1() SELECT '����' AS test; +CREATE FUNCTION f1() RETURNS CHAR(10) RETURN '����'; CREATE TABLE t1(c1 CHAR(10)); CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW -SET NEW.c1 = 'ÔÅÓÔ'; -CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT 'ÔÅÓÔ' AS test; +SET NEW.c1 = '����'; +CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT '����' AS test; set names utf8; SHOW CREATE VIEW v1; View Create View character_set_client collation_connection diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 0aec44b70f1..6dee239e21e 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -840,6 +840,8 @@ show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL View 'test.v1' references invalid table(s) or column(s) or function(s) or define +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 drop view v1; drop table t1; create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1; diff --git a/mysql-test/suite/federated/federated_bug_35333.result b/mysql-test/suite/federated/federated_bug_35333.result new file mode 100644 index 00000000000..7ea1b374712 --- /dev/null +++ b/mysql-test/suite/federated/federated_bug_35333.result @@ -0,0 +1,67 @@ +# +# Bug 35333 "If a Federated table can't connect to the remote hose, can't retrieve metadata" +# +# Queries such as SHOW TABLE STATUS and SELECT * FROM INFORMATION_SCHEMA.TABLES fail +# when encountering a federated table that cannot connect to its remote table. +# +# The fix is to store the error text in the TABLE COMMENTS column of I_S.TABLES, clear +# the remote connection error and push a warning instead. This allows the SELECT operation +# to complete while still indicating a problem. This fix applies to any non-fatal system +# error that occurs during a query against I_S.TABLES.de +CREATE DATABASE federated; +CREATE DATABASE federated; +CREATE DATABASE IF NOT EXISTS realdb; +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +# +# Create the base table to be referenced +# +CREATE TABLE realdb.t0 (a text, b text) ENGINE=MYISAM; +# +# Create a federated table with a bogus port number +# +CREATE TABLE federated.t0 (a text, b text) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:63333/realdb/t0'; +# +# Trigger a federated system error during a INFORMATION_SCHEMA.TABLES query +# +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT +FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'realdb' or TABLE_SCHEMA = 'federated'; +TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE ROW_FORMAT TABLE_ROWS DATA_LENGTH TABLE_COMMENT +federated t0 BASE TABLE FEDERATED NULL 0 Unable to connect to foreign data source: Can't connect to MySQL server on '127. +realdb t0 BASE TABLE MyISAM Dynamic 0 0 +Warnings: +Warning 1429 Unable to connect to foreign data source: Can't connect to MySQL server on '127.0.0.1' (socket errno) +SHOW WARNINGS; +Level Code Message +Warning 1429 Unable to connect to foreign data source: Can't connect to MySQL server on '127.0.0.1' (socket errno) +# +# Create a MyISAM table then corrupt the file +# +USE realdb; +CREATE TABLE t1 (c1 int) ENGINE=MYISAM; +# +# Corrupt the MyISAM table by deleting the base file +# +# +# Trigger a MyISAM system error during an INFORMATION_SCHEMA.TABLES query +# +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT +FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE ROW_FORMAT TABLE_ROWS DATA_LENGTH TABLE_COMMENT +realdb t1 BASE TABLE NULL NULL NULL NULL Can't find file: 't1' (errno: 2) +Warnings: +Warning 1017 Can't find file: 't1' (errno: 2) +SHOW WARNINGS; +Level Code Message +Warning 1017 Can't find file: 't1' (errno: 2) +# +# Cleanup +# +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +DROP DATABASE realdb; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE federated; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE federated; diff --git a/mysql-test/suite/federated/federated_bug_35333.test b/mysql-test/suite/federated/federated_bug_35333.test new file mode 100644 index 00000000000..58c217d24f2 --- /dev/null +++ b/mysql-test/suite/federated/federated_bug_35333.test @@ -0,0 +1,74 @@ +--echo # +--echo # Bug 35333 "If a Federated table can't connect to the remote hose, can't retrieve metadata" +--echo # +--echo # Queries such as SHOW TABLE STATUS and SELECT * FROM INFORMATION_SCHEMA.TABLES fail +--echo # when encountering a federated table that cannot connect to its remote table. +--echo # +--echo # The fix is to store the error text in the TABLE COMMENTS column of I_S.TABLES, clear +--echo # the remote connection error and push a warning instead. This allows the SELECT operation +--echo # to complete while still indicating a problem. This fix applies to any non-fatal system +--echo # error that occurs during a query against I_S.TABLES.de + +--source federated.inc + +--disable_warnings +CREATE DATABASE IF NOT EXISTS realdb; +# Federated database exists +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +--enable_warnings + +--echo # +--echo # Create the base table to be referenced +--echo # +CREATE TABLE realdb.t0 (a text, b text) ENGINE=MYISAM; + +--echo # +--echo # Create a federated table with a bogus port number +--echo # +CREATE TABLE federated.t0 (a text, b text) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:63333/realdb/t0'; + +#--warning ER_CONNECT_TO_FOREIGN_DATA_SOURCE + +--echo # +--echo # Trigger a federated system error during a INFORMATION_SCHEMA.TABLES query +--echo # +# Remove O/S-specific socket error +--replace_regex /\(.*\)/(socket errno)/ +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT + FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'realdb' or TABLE_SCHEMA = 'federated'; + +# Remove O/S-specific socket error +--replace_regex /\(.*\)/(socket errno)/ +SHOW WARNINGS; + +--echo # +--echo # Create a MyISAM table then corrupt the file +--echo # +USE realdb; +CREATE TABLE t1 (c1 int) ENGINE=MYISAM; +--echo # +--echo # Corrupt the MyISAM table by deleting the base file +--echo # +let $MYSQLD_DATADIR= `SELECT @@datadir`; +--remove_file $MYSQLD_DATADIR/realdb/t1.MYD +--remove_file $MYSQLD_DATADIR/realdb/t1.MYI + +--echo # +--echo # Trigger a MyISAM system error during an INFORMATION_SCHEMA.TABLES query +--echo # +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT + FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; + +SHOW WARNINGS; +--echo # +--echo # Cleanup +--echo # +--disable_warnings +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +DROP DATABASE realdb; +--enable_warnings + +--source federated_cleanup.inc diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 9b344204d64..ee0e2bf5ce7 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3636,28 +3636,28 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, { const char *tmp_buff; MYSQL_TIME time; + int info_error= 0; CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_tables_record"); restore_record(table, s->default_values); table->field[1]->store(db_name->str, db_name->length, cs); table->field[2]->store(table_name->str, table_name->length, cs); + if (res) { - /* - there was errors during opening tables - */ - const char *error= thd->is_error() ? thd->main_da.message() : ""; + /* There was a table open error, so set the table type and return */ if (tables->view) table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); else if (tables->schema_table) table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs); else table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs); - table->field[20]->store(error, strlen(error), cs); - thd->clear_error(); + + goto err; } - else if (tables->view) + + if (tables->view) { table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); table->field[20]->store(STRING_WITH_LEN("VIEW"), cs); @@ -3746,9 +3746,14 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, if (share->comment.str) table->field[20]->store(share->comment.str, share->comment.length, cs); - if(file) + if (file) { - file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO); + /* If info() fails, then there's nothing else to do */ + if ((info_error= file->info(HA_STATUS_VARIABLE | + HA_STATUS_TIME | + HA_STATUS_AUTO)) != 0) + goto err; + enum row_type row_type = file->get_row_type(); switch (row_type) { case ROW_TYPE_NOT_USED: @@ -3826,6 +3831,26 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, } } } + +err: + if (res || info_error) + { + /* + If an error was encountered, push a warning, set the TABLE COMMENT + column with the error text, and clear the error so that the operation + can continue. + */ + const char *error= thd->is_error() ? thd->main_da.message() : ""; + table->field[20]->store(error, strlen(error), cs); + + if (thd->is_error()) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + thd->main_da.sql_errno(), thd->main_da.message()); + thd->clear_error(); + } + } + DBUG_RETURN(schema_table_store_record(thd, table)); } From 5094555e53707babd62057c9ba637f79cc8e29e9 Mon Sep 17 00:00:00 2001 From: Christopher Powers Date: Tue, 30 Nov 2010 09:43:50 -0600 Subject: [PATCH 038/110] Bug#35333, "If Federated table can't connect to remote host, can't retrieve metadata" --- mysql-test/r/show_check.result | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 5f444759346..1aa3d62fc70 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1198,7 +1198,7 @@ set names koi8r; DROP DATABASE IF EXISTS mysqltest1; CREATE DATABASE mysqltest1; use mysqltest1; -CREATE TABLE t1(�������1 INT); +CREATE TABLE t1(ËÏÌÏÎËÁ1 INT); ---> Dumping mysqltest1 to outfile1 @@ -1210,7 +1210,7 @@ DROP DATABASE mysqltest1; SHOW CREATE TABLE mysqltest1.t1; Table Create Table t1 CREATE TABLE `t1` ( - `�������1` int(11) DEFAULT NULL + `ËÏÌÏÎËÁ1` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP DATABASE mysqltest1; use test; @@ -1417,14 +1417,14 @@ DROP PROCEDURE IF EXISTS p1; DROP FUNCTION IF EXISTS f1; DROP TABLE IF EXISTS t1; DROP EVENT IF EXISTS ev1; -CREATE VIEW v1 AS SELECT '����' AS test; -CREATE PROCEDURE p1() SELECT '����' AS test; -CREATE FUNCTION f1() RETURNS CHAR(10) RETURN '����'; +CREATE VIEW v1 AS SELECT 'ÔÅÓÔ' AS test; +CREATE PROCEDURE p1() SELECT 'ÔÅÓÔ' AS test; +CREATE FUNCTION f1() RETURNS CHAR(10) RETURN 'ÔÅÓÔ'; CREATE TABLE t1(c1 CHAR(10)); CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW -SET NEW.c1 = '����'; -CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT '����' AS test; +SET NEW.c1 = 'ÔÅÓÔ'; +CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT 'ÔÅÓÔ' AS test; set names utf8; SHOW CREATE VIEW v1; View Create View character_set_client collation_connection From 23636330c96cfc158881393cd1a99bcc069cd75f Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 30 Nov 2010 16:55:28 +0000 Subject: [PATCH 039/110] BUG#57288: binlog_tmp_table fails sporadically: "Failed to write the DROP statement ..." Problem: When using temporary tables and closing a session, an implicit DROP TEMPORARY TABLE IF EXISTS is written to the binary log (while cleaning up the context of the session THD - see: sql_class.cc:THD::cleanup which calls close_temporary_tables). close_temporary_tables, first checks if the binary log is opened and then proceeds to creating the DROP statements. Then, such statements, are written to the binary log through MYSQL_BIN_LOG::write(Log_event *). Inside, there is another check if the binary log is opened and if not an error is returned. This is where the faulty behavior is triggered. Given that the test case replays a binary log, with temp tables statements, and right after it issues RESET MASTER, there is a chance that is_open will report false (when the mysql session is closed and the temporary tables are written). is_open may return false, because MYSQL_BIN_LOG::reset_logs is not setting the correct flag (LOG_CLOSE_TO_BE_OPENED), on the MYSQL_LOG_BIN::log_state (instead it sets just the LOG_CLOSE_INDEX flag, leaving the log_state to LOG_CLOSED). Thence, when writing the DROP statement as part of the THD::cleanup, the thread could get a return value of false for is_open - inside MYSQL_BIN_LOG::write, ultimately reporting that it can't write the event to the binary log. Fix: We fix this by adding the correct flag, missing in the second close. --- sql/log.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/log.cc b/sql/log.cc index 38f4677f06f..cff69b4cf51 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3037,7 +3037,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) } /* Start logging with a new file */ - close(LOG_CLOSE_INDEX); + close(LOG_CLOSE_INDEX | LOG_CLOSE_TO_BE_OPENED); if ((error= my_delete_allow_opened(index_file_name, MYF(0)))) // Reset (open will update) { if (my_errno == ENOENT) From f918f1263a1009e98c95780935563eeb0e553f64 Mon Sep 17 00:00:00 2001 From: Christopher Powers Date: Tue, 30 Nov 2010 11:20:56 -0600 Subject: [PATCH 040/110] Bug#35333, "If Federated table can't connect to remote host, can't retrieve metadata" Improved error handling such that queries against Information_Schema.Tables won't fail if a federated table can't make a remote connection. --- mysql-test/r/lock_multi.result | 2 + mysql-test/r/mdl_sync.result | 2 + mysql-test/r/merge.result | 2 + mysql-test/r/show_check.result | 2 + mysql-test/r/view.result | 2 + .../federated/federated_bug_35333.result | 67 +++++++++++++++++ .../suite/federated/federated_bug_35333.test | 74 +++++++++++++++++++ sql/sql_show.cc | 62 ++++++++++++++-- 8 files changed, 205 insertions(+), 8 deletions(-) create mode 100644 mysql-test/suite/federated/federated_bug_35333.result create mode 100644 mysql-test/suite/federated/federated_bug_35333.test diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 99e1f54e762..1a8ef2deefd 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -430,6 +430,8 @@ SELECT table_name, table_comment FROM information_schema.tables WHERE table_schema= 'test' AND table_name= 't1'; table_name table_comment t1 Lock wait timeout exceeded; try restarting transaction +Warnings: +Warning 1205 Lock wait timeout exceeded; try restarting transaction # Connection default UNLOCK TABLES; # Connection con3 diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result index 594cf433692..b2e71faf741 100644 --- a/mysql-test/r/mdl_sync.result +++ b/mysql-test/r/mdl_sync.result @@ -2322,6 +2322,8 @@ select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t2'; table_name table_type auto_increment table_comment t2 BASE TABLE NULL Table 'test'.'t2' was skipped since its definition is being modified by concurrent DDL statement +Warnings: +Warning 1684 Table 'test'.'t2' was skipped since its definition is being modified by concurrent DDL statement # Switching to connection 'default'. unlock tables; # Switching to connection 'con46044'. diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index ace834a26c2..f668761cb16 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2084,6 +2084,8 @@ SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' and TABLE_NAME='tm1'; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT def test tm1 BASE TABLE NULL NULL NULL # # # # # # # # # # NULL # # Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +Warnings: +Warning 1168 Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist DROP TABLE tm1; CREATE TABLE t1(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; CREATE TABLE t2(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 5e41e6b29c6..d42cb680112 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -663,6 +663,8 @@ flush tables; SHOW TABLE STATUS like 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect information in file: './test/t1.frm' +Warnings: +Warning 1033 Incorrect information in file: './test/t1.frm' show create table t1; ERROR HY000: Incorrect information in file: './test/t1.frm' drop table if exists t1; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 777ac9c258f..8d39b4e596b 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -840,6 +840,8 @@ show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +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 drop view v1; drop table t1; create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1; diff --git a/mysql-test/suite/federated/federated_bug_35333.result b/mysql-test/suite/federated/federated_bug_35333.result new file mode 100644 index 00000000000..ca7aa960b73 --- /dev/null +++ b/mysql-test/suite/federated/federated_bug_35333.result @@ -0,0 +1,67 @@ +# +# Bug 35333 "If a Federated table can't connect to the remote hose, can't retrieve metadata" +# +# Queries such as SHOW TABLE STATUS and SELECT * FROM INFORMATION_SCHEMA.TABLES fail +# when encountering a federated table that cannot connect to its remote table. +# +# The fix is to store the error text in the TABLE COMMENTS column of I_S.TABLES, clear +# the remote connection error and push a warning instead. This allows the SELECT operation +# to complete while still indicating a problem. This fix applies to any non-fatal system +# error that occurs during a query against I_S.TABLES.de +CREATE DATABASE federated; +CREATE DATABASE federated; +CREATE DATABASE IF NOT EXISTS realdb; +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +# +# Create the base table to be referenced +# +CREATE TABLE realdb.t0 (a text, b text) ENGINE=MYISAM; +# +# Create a federated table with a bogus port number +# +CREATE TABLE federated.t0 (a text, b text) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:63333/realdb/t0'; +# +# Trigger a federated system error during a INFORMATION_SCHEMA.TABLES query +# +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT +FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'realdb' or TABLE_SCHEMA = 'federated'; +TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE ROW_FORMAT TABLE_ROWS DATA_LENGTH TABLE_COMMENT +federated t0 BASE TABLE FEDERATED NULL 0 Unable to connect to foreign data source: Can't connect to MySQL server on '127.0.0.1' (socket errno) +realdb t0 BASE TABLE MyISAM Dynamic 0 0 +Warnings: +Warning 1429 Unable to connect to foreign data source: Can't connect to MySQL server on '127.0.0.1' (socket errno) +SHOW WARNINGS; +Level Code Message +Warning 1429 Unable to connect to foreign data source: Can't connect to MySQL server on '127.0.0.1' (socket errno) +# +# Create a MyISAM table then corrupt the file +# +USE realdb; +CREATE TABLE t1 (c1 int) ENGINE=MYISAM; +# +# Corrupt the MyISAM table by deleting the base file +# +# +# Trigger a MyISAM system error during an INFORMATION_SCHEMA.TABLES query +# +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT +FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE ROW_FORMAT TABLE_ROWS DATA_LENGTH TABLE_COMMENT +realdb t1 BASE TABLE NULL NULL NULL NULL Can't find file: 't1' (errno: 2) +Warnings: +Warning 1017 Can't find file: 't1' (errno: 2) +SHOW WARNINGS; +Level Code Message +Warning 1017 Can't find file: 't1' (errno: 2) +# +# Cleanup +# +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +DROP DATABASE realdb; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE federated; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE federated; diff --git a/mysql-test/suite/federated/federated_bug_35333.test b/mysql-test/suite/federated/federated_bug_35333.test new file mode 100644 index 00000000000..58c217d24f2 --- /dev/null +++ b/mysql-test/suite/federated/federated_bug_35333.test @@ -0,0 +1,74 @@ +--echo # +--echo # Bug 35333 "If a Federated table can't connect to the remote hose, can't retrieve metadata" +--echo # +--echo # Queries such as SHOW TABLE STATUS and SELECT * FROM INFORMATION_SCHEMA.TABLES fail +--echo # when encountering a federated table that cannot connect to its remote table. +--echo # +--echo # The fix is to store the error text in the TABLE COMMENTS column of I_S.TABLES, clear +--echo # the remote connection error and push a warning instead. This allows the SELECT operation +--echo # to complete while still indicating a problem. This fix applies to any non-fatal system +--echo # error that occurs during a query against I_S.TABLES.de + +--source federated.inc + +--disable_warnings +CREATE DATABASE IF NOT EXISTS realdb; +# Federated database exists +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +--enable_warnings + +--echo # +--echo # Create the base table to be referenced +--echo # +CREATE TABLE realdb.t0 (a text, b text) ENGINE=MYISAM; + +--echo # +--echo # Create a federated table with a bogus port number +--echo # +CREATE TABLE federated.t0 (a text, b text) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:63333/realdb/t0'; + +#--warning ER_CONNECT_TO_FOREIGN_DATA_SOURCE + +--echo # +--echo # Trigger a federated system error during a INFORMATION_SCHEMA.TABLES query +--echo # +# Remove O/S-specific socket error +--replace_regex /\(.*\)/(socket errno)/ +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT + FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'realdb' or TABLE_SCHEMA = 'federated'; + +# Remove O/S-specific socket error +--replace_regex /\(.*\)/(socket errno)/ +SHOW WARNINGS; + +--echo # +--echo # Create a MyISAM table then corrupt the file +--echo # +USE realdb; +CREATE TABLE t1 (c1 int) ENGINE=MYISAM; +--echo # +--echo # Corrupt the MyISAM table by deleting the base file +--echo # +let $MYSQLD_DATADIR= `SELECT @@datadir`; +--remove_file $MYSQLD_DATADIR/realdb/t1.MYD +--remove_file $MYSQLD_DATADIR/realdb/t1.MYI + +--echo # +--echo # Trigger a MyISAM system error during an INFORMATION_SCHEMA.TABLES query +--echo # +SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT + FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; + +SHOW WARNINGS; +--echo # +--echo # Cleanup +--echo # +--disable_warnings +DROP TABLE IF EXISTS realdb.t0; +DROP TABLE IF EXISTS federated.t0; +DROP DATABASE realdb; +--enable_warnings + +--source federated_cleanup.inc diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f8853611b39..2c71fe5dd48 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3781,6 +3781,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, { const char *tmp_buff; MYSQL_TIME time; + int info_error= 0; CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_tables_record"); @@ -3788,22 +3789,21 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, table->field[0]->store(STRING_WITH_LEN("def"), cs); table->field[1]->store(db_name->str, db_name->length, cs); table->field[2]->store(table_name->str, table_name->length, cs); + if (res) { - /* - there was errors during opening tables - */ - const char *error= thd->is_error() ? thd->stmt_da->message() : ""; + /* There was a table open error, so set the table type and return */ if (tables->view) table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); else if (tables->schema_table) table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs); else table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs); - table->field[20]->store(error, strlen(error), cs); - thd->clear_error(); + + goto err; } - else if (tables->view) + + if (tables->view) { table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); table->field[20]->store(STRING_WITH_LEN("VIEW"), cs); @@ -3818,6 +3818,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, #ifdef WITH_PARTITION_STORAGE_ENGINE bool is_partitioned= FALSE; #endif + if (share->tmp_table == SYSTEM_TMP_TABLE) table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs); else if (share->tmp_table) @@ -3831,6 +3832,9 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, continue; table->field[i]->set_notnull(); } + + /* Collect table info from the table share */ + #ifdef WITH_PARTITION_STORAGE_ENGINE if (share->db_type() == partition_hton && share->partition_info_str_len) @@ -3839,62 +3843,82 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, is_partitioned= TRUE; } #endif + tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type); table->field[4]->store(tmp_buff, strlen(tmp_buff), cs); table->field[5]->store((longlong) share->frm_version, TRUE); ptr=option_buff; + if (share->min_rows) { ptr=strmov(ptr," min_rows="); ptr=longlong10_to_str(share->min_rows,ptr,10); } + if (share->max_rows) { ptr=strmov(ptr," max_rows="); ptr=longlong10_to_str(share->max_rows,ptr,10); } + if (share->avg_row_length) { ptr=strmov(ptr," avg_row_length="); ptr=longlong10_to_str(share->avg_row_length,ptr,10); } + if (share->db_create_options & HA_OPTION_PACK_KEYS) ptr=strmov(ptr," pack_keys=1"); + if (share->db_create_options & HA_OPTION_NO_PACK_KEYS) ptr=strmov(ptr," pack_keys=0"); + /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */ if (share->db_create_options & HA_OPTION_CHECKSUM) ptr=strmov(ptr," checksum=1"); + if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE) ptr=strmov(ptr," delay_key_write=1"); + if (share->row_type != ROW_TYPE_DEFAULT) ptr=strxmov(ptr, " row_format=", ha_row_type[(uint) share->row_type], NullS); + if (share->key_block_size) { ptr= strmov(ptr, " KEY_BLOCK_SIZE="); ptr= longlong10_to_str(share->key_block_size, ptr, 10); } + #ifdef WITH_PARTITION_STORAGE_ENGINE if (is_partitioned) ptr= strmov(ptr, " partitioned"); #endif + table->field[19]->store(option_buff+1, (ptr == option_buff ? 0 : (uint) (ptr-option_buff)-1), cs); tmp_buff= (share->table_charset ? share->table_charset->name : "default"); + table->field[17]->store(tmp_buff, strlen(tmp_buff), cs); if (share->comment.str) table->field[20]->store(share->comment.str, share->comment.length, cs); + /* Collect table info from the storage engine */ + if(file) { - file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO); + /* If info() fails, then there's nothing else to do */ + if ((info_error= file->info(HA_STATUS_VARIABLE | + HA_STATUS_TIME | + HA_STATUS_AUTO)) != 0) + goto err; + enum row_type row_type = file->get_row_type(); switch (row_type) { case ROW_TYPE_NOT_USED: @@ -3923,7 +3947,9 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, tmp_buff= "Paged"; break; } + table->field[6]->store(tmp_buff, strlen(tmp_buff), cs); + if (!tables->schema_table) { table->field[7]->store((longlong) file->stats.records, TRUE); @@ -3972,6 +3998,26 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, } } } + +err: + if (res || info_error) + { + /* + If an error was encountered, push a warning, set the TABLE COMMENT + column with the error text, and clear the error so that the operation + can continue. + */ + const char *error= thd->is_error() ? thd->stmt_da->message() : ""; + table->field[20]->store(error, strlen(error), cs); + + if (thd->is_error()) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + thd->stmt_da->sql_errno(), thd->stmt_da->message()); + thd->clear_error(); + } + } + DBUG_RETURN(schema_table_store_record(thd, table)); } From a186085a077c3f22827496a86c4029c8fd1384af Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Tue, 30 Nov 2010 18:52:38 +0100 Subject: [PATCH 041/110] Bug #58414 mysql_upgrade fails on dump upgrade between 5.1.53 -> 5.5.8 The problem was that mysql_upgrade failed because DROP DATABASE refused to drop the 'performance_schema' database when the mysql.proc table definition was made temporarily invalid by dump import. This patch fixes the problem by adding the error resulting from opening a damaged mysq.proc table (ER_CANNOT_LOAD_FROM_TABLE), to the list of errors DROP DATABASE will ignore when trying to lock stored procedures and functions before deletion. This problem was a regression introduced by the patch for Bug#57663. Test case added to sp-destruct.test. --- mysql-test/r/sp-destruct.result | 18 ++++++++++++++++++ mysql-test/t/sp-destruct.test | 27 +++++++++++++++++++++++++++ sql/sp.cc | 2 ++ 3 files changed, 47 insertions(+) diff --git a/mysql-test/r/sp-destruct.result b/mysql-test/r/sp-destruct.result index 32d0e39c5af..a3c8574d141 100644 --- a/mysql-test/r/sp-destruct.result +++ b/mysql-test/r/sp-destruct.result @@ -150,3 +150,21 @@ Warnings: Error 1547 Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted # Restore mysql.proc. drop table mysql.proc; +# +# Bug#58414 mysql_upgrade fails on dump upgrade between 5.1.53 -> 5.5.8 +# +DROP TABLE IF EXISTS proc_backup; +DROP DATABASE IF EXISTS db1; +# Backup the proc table +RENAME TABLE mysql.proc TO proc_backup; +CREATE TABLE mysql.proc LIKE proc_backup; +CREATE DATABASE db1; +CREATE PROCEDURE db1.p1() SET @foo = 10; +# Modify a field of the table. +ALTER TABLE mysql.proc MODIFY comment CHAR (32); +DROP DATABASE db1; +Warnings: +Error 1548 Cannot load from mysql.proc. The table is probably corrupted +# Restore mysql.proc +DROP TABLE mysql.proc; +RENAME TABLE proc_backup TO mysql.proc; diff --git a/mysql-test/t/sp-destruct.test b/mysql-test/t/sp-destruct.test index a5c287e44a8..b4aa9ea1959 100644 --- a/mysql-test/t/sp-destruct.test +++ b/mysql-test/t/sp-destruct.test @@ -252,3 +252,30 @@ drop table mysql.proc; --remove_file $MYSQLTEST_VARDIR/tmp/proc.frm --remove_file $MYSQLTEST_VARDIR/tmp/proc.MYD --remove_file $MYSQLTEST_VARDIR/tmp/proc.MYI + + +--echo # +--echo # Bug#58414 mysql_upgrade fails on dump upgrade between 5.1.53 -> 5.5.8 +--echo # + +--disable_warnings +DROP TABLE IF EXISTS proc_backup; +DROP DATABASE IF EXISTS db1; +--enable_warnings + +--echo # Backup the proc table +RENAME TABLE mysql.proc TO proc_backup; +CREATE TABLE mysql.proc LIKE proc_backup; + +CREATE DATABASE db1; +CREATE PROCEDURE db1.p1() SET @foo = 10; + +--echo # Modify a field of the table. +ALTER TABLE mysql.proc MODIFY comment CHAR (32); + +# This should not fail even if mysql.proc is invalid. +DROP DATABASE db1; + +--echo # Restore mysql.proc +DROP TABLE mysql.proc; +RENAME TABLE proc_backup TO mysql.proc; diff --git a/sql/sp.cc b/sql/sp.cc index 71a5afb437c..ae11c2ad14c 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1372,6 +1372,8 @@ public: MYSQL_ERROR ** cond_hdl) { if (sql_errno == ER_NO_SUCH_TABLE || + sql_errno == ER_CANNOT_LOAD_FROM_TABLE || + sql_errno == ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE || sql_errno == ER_COL_COUNT_DOESNT_MATCH_CORRUPTED) return true; return false; From 2419cec9f1ca35053feca7311a2f8d94f4198606 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 30 Nov 2010 21:07:55 -0200 Subject: [PATCH 042/110] Workaround a GCC warning about a pointer being cast to a larger integral type. Use intptr which is designed to hold pointer values and pass it to off_t. --- mysys/stacktrace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index b6bf88cf3e1..93e8ae6b508 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -87,8 +87,11 @@ static int safe_print_str(const char *addr, int max_len) if ((fd= open(buf, O_RDONLY)) < 0) return -1; + /* Ensure that off_t can hold a pointer. */ + compile_time_assert(sizeof(off_t) >= sizeof(intptr)); + total= max_len; - offset= (off_t) addr; + offset= (intptr) addr; /* Read up to the maximum number of bytes. */ while (total) From 86ec0f98b805b00a03ce9dc6d7147580b824489c Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 30 Nov 2010 21:19:49 -0200 Subject: [PATCH 043/110] Bug#56760: my_atomics failures on osx10.5-x86-64bit The problem was due to a misuse of GCC asm constraints used to implement a atomic load. On x86_64, the load was implemented as a cmpxchg which implicitly uses the eax register as a source and destination operand, yet the dummy value used for comparison wasn't being properly loaded into eax (and other problems). The core problem is that cmpxchg is unnecessary as a load on x86_64 as there are other simpler instructions such as xadd. Even though, such instructions are only used to have a memory barrier as load and stores are atomic by definition. Hence, the solution is to explicitly issue the required CPU and compiler barriers. --- include/atomic/x86-gcc.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/atomic/x86-gcc.h b/include/atomic/x86-gcc.h index 90602ef900c..ea3202aa9c9 100644 --- a/include/atomic/x86-gcc.h +++ b/include/atomic/x86-gcc.h @@ -78,15 +78,15 @@ : "memory") /* - Actually 32-bit reads/writes are always atomic on x86 - But we add LOCK_prefix here anyway to force memory barriers + Actually 32/64-bit reads/writes are always atomic on x86_64, + nonetheless issue memory barriers as appropriate. */ #define make_atomic_load_body(S) \ - ret=0; \ - asm volatile (LOCK_prefix "; cmpxchg %2, %0" \ - : "=m" (*a), "=a" (ret) \ - : "r" (ret), "m" (*a) \ - : "memory") + /* Serialize prior load and store operations. */ \ + asm volatile ("mfence" ::: "memory"); \ + ret= *a; \ + /* Prevent compiler from reordering instructions. */ \ + asm volatile ("" ::: "memory") #define make_atomic_store_body(S) \ asm volatile ("; xchg %0, %1;" \ : "=m" (*a), "+r" (v) \ From aaefb52df8e8bcf67faaa5b1cf4b2de6c83f408a Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 30 Nov 2010 23:32:51 +0000 Subject: [PATCH 044/110] BUG#46166: MYSQL_BIN_LOG::new_file_impl is not propagating error when generating new name. If find_uniq_filename returns an error, then this error is not being propagated upwards, and execution does not report error to the user (although a entry in the error log is generated). Additionally, some more errors were ignored in new_file_impl: - when writing the rotate event - when reopening the index and binary log file This patch addresses this by propagating the error up in the execution stack. Furthermore, when rotation of the binary log fails, an incident event is written, because there may be a chance that some changes for a given statement, were not properly logged. For example, in SBR, LOAD DATA INFILE statement requires more than one event to be logged, should rotation fail while logging part of the LOAD DATA events, then the logged data would become inconsistent with the data in the storage engine. --- mysql-test/include/io_thd_fault_injection.inc | 21 + mysql-test/include/restart_mysqld.inc | 6 +- mysql-test/suite/binlog/r/binlog_index.result | 36 +- mysql-test/suite/binlog/t/binlog_index.test | 26 +- .../suite/rpl/r/rpl_binlog_errors.result | 274 ++++++++++++ .../suite/rpl/t/rpl_binlog_errors-master.opt | 1 + mysql-test/suite/rpl/t/rpl_binlog_errors.test | 413 ++++++++++++++++++ sql/handler.cc | 6 +- sql/log.cc | 152 +++++-- sql/log.h | 16 +- sql/mysql_priv.h | 2 +- sql/mysqld.cc | 2 +- sql/rpl_injector.cc | 6 +- sql/slave.cc | 11 +- sql/slave.h | 2 +- sql/sql_load.cc | 7 + sql/sql_parse.cc | 50 ++- 17 files changed, 958 insertions(+), 73 deletions(-) create mode 100644 mysql-test/include/io_thd_fault_injection.inc create mode 100644 mysql-test/suite/rpl/r/rpl_binlog_errors.result create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_errors.test diff --git a/mysql-test/include/io_thd_fault_injection.inc b/mysql-test/include/io_thd_fault_injection.inc new file mode 100644 index 00000000000..a76e46d772a --- /dev/null +++ b/mysql-test/include/io_thd_fault_injection.inc @@ -0,0 +1,21 @@ +# +# Takes the flag as an argument: +# -- let $io_thd_injection_fault_flag=+d,fault_injection_new_file_rotate_event +# -- source include/io_thd_fault_injection.inc +# + +SET @old_debug=@@global.debug; +-- disable_warnings +-- source include/stop_slave.inc +-- enable_warnings +-- eval SET GLOBAL debug="+d,$io_thd_injection_fault_flag" + +START SLAVE io_thread; +-- source include/wait_for_slave_io_to_stop.inc +-- source include/wait_for_slave_io_error.inc + +-- eval SET GLOBAL debug="-d,$io_thd_injection_fault_flag" +SET GLOBAL debug=@old_debug; + +# restart because slave is in bad shape +-- source include/restart_mysqld.inc diff --git a/mysql-test/include/restart_mysqld.inc b/mysql-test/include/restart_mysqld.inc index d92115f0a61..f750385e300 100644 --- a/mysql-test/include/restart_mysqld.inc +++ b/mysql-test/include/restart_mysqld.inc @@ -1,14 +1,16 @@ # Write file to make mysql-test-run.pl expect the "crash", but don't start # it until it's told to ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--let $_server_id= `SELECT @@server_id` +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect +--exec echo "wait" > $_expect_file_name # Send shutdown to the connected server and give # it 10 seconds to die before zapping it shutdown_server 10; # Write file to make mysql-test-run.pl start up the server again ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--exec echo "restart" > $_expect_file_name # Turn on reconnect --enable_reconnect diff --git a/mysql-test/suite/binlog/r/binlog_index.result b/mysql-test/suite/binlog/r/binlog_index.result index 52d698e9f96..6b422b82191 100644 --- a/mysql-test/suite/binlog/r/binlog_index.result +++ b/mysql-test/suite/binlog/r/binlog_index.result @@ -2,7 +2,9 @@ call mtr.add_suppression('Attempting backtrace'); call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered files that would be purged.'); call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file'); call mtr.add_suppression('Turning logging off for the whole duration of the MySQL server process.'); +call mtr.add_suppression('Could not open .*'); call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before purging logs.'); +RESET MASTER; flush logs; flush logs; flush logs; @@ -116,11 +118,31 @@ master-bin.000011 # This should put the server in unsafe state and stop # accepting any command. If we inject a fault at this # point and continue the execution the server crashes. -# Besides the flush command does not report an error. # +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 +master-bin.000008 +master-bin.000009 +master-bin.000010 +master-bin.000011 + # fault_injection_registering_index SET SESSION debug="+d,fault_injection_registering_index"; flush logs; +ERROR HY000: Can't open file: './master-bin.000012' (errno: 1) +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 +master-bin.000008 +master-bin.000009 +master-bin.000010 +master-bin.000011 + SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); SELECT @index; @index @@ -135,6 +157,18 @@ master-bin.000012 # fault_injection_updating_index SET SESSION debug="+d,fault_injection_updating_index"; flush logs; +ERROR HY000: Can't open file: './master-bin.000013' (errno: 1) +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 +master-bin.000008 +master-bin.000009 +master-bin.000010 +master-bin.000011 +master-bin.000012 + SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); SELECT @index; @index diff --git a/mysql-test/suite/binlog/t/binlog_index.test b/mysql-test/suite/binlog/t/binlog_index.test index 9d4a49602a6..d2b34083182 100644 --- a/mysql-test/suite/binlog/t/binlog_index.test +++ b/mysql-test/suite/binlog/t/binlog_index.test @@ -10,9 +10,12 @@ call mtr.add_suppression('Attempting backtrace'); call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered files that would be purged.'); call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file'); call mtr.add_suppression('Turning logging off for the whole duration of the MySQL server process.'); +call mtr.add_suppression('Could not open .*'); call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before purging logs.'); let $old=`select @@debug`; +RESET MASTER; + let $MYSQLD_DATADIR= `select @@datadir`; let $INDEX=$MYSQLD_DATADIR/master-bin.index; @@ -205,12 +208,25 @@ SELECT @index; --echo # This should put the server in unsafe state and stop --echo # accepting any command. If we inject a fault at this --echo # point and continue the execution the server crashes. ---echo # Besides the flush command does not report an error. --echo # +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + --echo # fault_injection_registering_index SET SESSION debug="+d,fault_injection_registering_index"; +-- error ER_CANT_OPEN_FILE flush logs; + +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + --source include/restart_mysqld.inc --chmod 0644 $INDEX @@ -221,7 +237,15 @@ SELECT @index; --echo # fault_injection_updating_index SET SESSION debug="+d,fault_injection_updating_index"; +-- error ER_CANT_OPEN_FILE flush logs; + +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + --source include/restart_mysqld.inc --chmod 0644 $INDEX diff --git a/mysql-test/suite/rpl/r/rpl_binlog_errors.result b/mysql-test/suite/rpl/r/rpl_binlog_errors.result new file mode 100644 index 00000000000..e67b60860ca --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_binlog_errors.result @@ -0,0 +1,274 @@ +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; +####################################################################### +####################### PART 1: MASTER TESTS ########################## +####################################################################### +include/stop_slave.inc +call mtr.add_suppression("Can't generate a unique log-filename"); +call mtr.add_suppression("Writing one row to the row-based binary log failed.*"); +call mtr.add_suppression("Error writing file .*"); +SET @old_debug= @@global.debug; +SELECT repeat('x',8192) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data'; +SELECT repeat('x',10) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166-2.data'; +RESET MASTER; +###################### TEST #1 +FLUSH LOGS; +# assert: must show two binlogs +show binary logs; +Log_name File_size +master-bin.000001 # +master-bin.000002 # +###################### TEST #2 +RESET MASTER; +SET GLOBAL debug="+d,error_unique_log_filename"; +FLUSH LOGS; +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) + +# assert: must show one binlog +show binary logs; +Log_name File_size +master-bin.000001 # +SET GLOBAL debug=""; +RESET MASTER; +###################### TEST #3 +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a TEXT) Engine=InnoDB; +CREATE TABLE t4 (a TEXT); +INSERT INTO t1 VALUES (1); +RESET MASTER; +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t2; +# assert: must show two binlog +show binary logs; +Log_name File_size +master-bin.000001 # +master-bin.000002 # +SET GLOBAL debug="-d,error_unique_log_filename"; +DELETE FROM t2; +RESET MASTER; +###################### TEST #4 +SET GLOBAL debug="+d,error_unique_log_filename"; +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t2; +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) + +# assert: must show one entry +SELECT count(*) FROM t2; +count(*) +1 +SET GLOBAL debug="-d,error_unique_log_filename"; +DELETE FROM t2; +RESET MASTER; +###################### TEST #5 +SET GLOBAL debug="+d,error_unique_log_filename"; +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166-2.data' INTO TABLE t2; +# assert: must show one entry +SELECT count(*) FROM t2; +count(*) +1 +SET GLOBAL debug="-d,error_unique_log_filename"; +DELETE FROM t2; +RESET MASTER; +###################### TEST #6 +SET GLOBAL debug="+d,error_unique_log_filename"; +SET AUTOCOMMIT=0; +INSERT INTO t2 VALUES ('muse'); +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t2; +INSERT INTO t2 VALUES ('muse'); +COMMIT; +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) + +# assert: must show three entries +SELECT count(*) FROM t2; +count(*) +3 +SET AUTOCOMMIT= 1; +SET GLOBAL debug="-d,error_unique_log_filename"; +DELETE FROM t2; +RESET MASTER; +###################### TEST #7 +SET GLOBAL debug="+d,error_unique_log_filename"; +SELECT count(*) FROM t4; +count(*) +0 +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t4; +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) + +# assert: must show 1 entry +SELECT count(*) FROM t4; +count(*) +1 +### check that the incident event is written to the current log +SET GLOBAL debug="-d,error_unique_log_filename"; +FLUSH LOGS; +SHOW BINLOG EVENTS IN 'BINLOG_FILE' FROM LIMIT 1; +Log_name Pos Event_type Server_id End_log_pos Info +BINLOG_FILE # Incident # # #1 (LOST_EVENTS) +DELETE FROM t4; +RESET MASTER; +###################### TEST #8 +SET GLOBAL debug="+d,error_unique_log_filename"; +# must show 0 entries +SELECT count(*) FROM t4; +count(*) +0 +SELECT count(*) FROM t2; +count(*) +0 +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t4; +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) + +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t2; +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) + +INSERT INTO t2 VALUES ('aaa'), ('bbb'), ('ccc'); +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) + +# INFO: Count(*) Before Offending DELETEs +# assert: must show 1 entry +SELECT count(*) FROM t4; +count(*) +1 +# assert: must show 4 entries +SELECT count(*) FROM t2; +count(*) +4 +DELETE FROM t4; +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) + +DELETE FROM t2; +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) + +# INFO: Count(*) After Offending DELETEs +# assert: must show zero entries +SELECT count(*) FROM t4; +count(*) +0 +SELECT count(*) FROM t2; +count(*) +0 +SET GLOBAL debug="-d,error_unique_log_filename"; +###################### TEST #9 +SET GLOBAL debug="+d,error_unique_log_filename"; +SET SQL_LOG_BIN=0; +INSERT INTO t2 VALUES ('aaa'), ('bbb'), ('ccc'), ('ddd'); +INSERT INTO t4 VALUES ('eee'), ('fff'), ('ggg'), ('hhh'); +# assert: must show four entries +SELECT count(*) FROM t2; +count(*) +4 +SELECT count(*) FROM t4; +count(*) +4 +DELETE FROM t2; +DELETE FROM t4; +# assert: must show zero entries +SELECT count(*) FROM t2; +count(*) +0 +SELECT count(*) FROM t4; +count(*) +0 +SET SQL_LOG_BIN=1; +SET GLOBAL debug="-d,error_unique_log_filename"; +###################### TEST #10 +call mtr.add_suppression("MSYQL_BIN_LOG::open failed to sync the index file."); +call mtr.add_suppression("Could not open .*"); +RESET MASTER; +SHOW WARNINGS; +Level Code Message +SET GLOBAL debug="+d,fault_injection_registering_index"; +FLUSH LOGS; +ERROR HY000: Can't open file: './master-bin.000002' (errno: 1) +SET GLOBAL debug="-d,fault_injection_registering_index"; +SHOW BINARY LOGS; +ERROR HY000: You are not using binary logging +CREATE TABLE t5 (a INT); +INSERT INTO t4 VALUES ('bbbbb'); +INSERT INTO t2 VALUES ('aaaaa'); +DELETE FROM t4; +DELETE FROM t2; +DROP TABLE t5; +###################### TEST #11 +SET GLOBAL debug="+d,fault_injection_openning_index"; +FLUSH LOGS; +ERROR HY000: Can't open file: './master-bin.index' (errno: 1) +SET GLOBAL debug="-d,fault_injection_openning_index"; +RESET MASTER; +ERROR HY000: Binlog closed, cannot RESET MASTER +CREATE TABLE t5 (a INT); +INSERT INTO t4 VALUES ('bbbbb'); +INSERT INTO t2 VALUES ('aaaaa'); +DELETE FROM t4; +DELETE FROM t2; +DROP TABLE t5; +###################### TEST #12 +SET GLOBAL debug="+d,fault_injection_new_file_rotate_event"; +FLUSH LOGS; +ERROR HY000: Can't open file: 'master-bin' (errno: 0) +SET GLOBAL debug="-d,fault_injection_new_file_rotate_event"; +RESET MASTER; +ERROR HY000: Binlog closed, cannot RESET MASTER +CREATE TABLE t5 (a INT); +INSERT INTO t4 VALUES ('bbbbb'); +INSERT INTO t2 VALUES ('aaaaa'); +DELETE FROM t4; +DELETE FROM t2; +DROP TABLE t5; +SET GLOBAL debug= @old_debug; +DROP TABLE t1, t2, t4; +RESET MASTER; +include/start_slave.inc +####################################################################### +####################### PART 2: SLAVE TESTS ########################### +####################################################################### +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; +call mtr.add_suppression("Slave I/O: Relay log write failure: could not queue event from master.*"); +call mtr.add_suppression("Error writing file .*"); +call mtr.add_suppression("Could not open .*"); +call mtr.add_suppression("MSYQL_BIN_LOG::open failed to sync the index file."); +call mtr.add_suppression("Can't generate a unique log-filename .*"); +###################### TEST #13 +SET @old_debug=@@global.debug; +include/stop_slave.inc +SET GLOBAL debug="+d,error_unique_log_filename"; +START SLAVE io_thread; +Last_IO_Error = Relay log write failure: could not queue event from master +SET GLOBAL debug="-d,error_unique_log_filename"; +SET GLOBAL debug=@old_debug; +###################### TEST #14 +SET @old_debug=@@global.debug; +include/stop_slave.inc +SET GLOBAL debug="+d,fault_injection_new_file_rotate_event"; +START SLAVE io_thread; +Last_IO_Error = Relay log write failure: could not queue event from master +SET GLOBAL debug="-d,fault_injection_new_file_rotate_event"; +SET GLOBAL debug=@old_debug; +###################### TEST #15 +SET @old_debug=@@global.debug; +include/stop_slave.inc +SET GLOBAL debug="+d,fault_injection_registering_index"; +START SLAVE io_thread; +Last_IO_Error = Relay log write failure: could not queue event from master +SET GLOBAL debug="-d,fault_injection_registering_index"; +SET GLOBAL debug=@old_debug; +###################### TEST #16 +SET @old_debug=@@global.debug; +include/stop_slave.inc +SET GLOBAL debug="+d,fault_injection_openning_index"; +START SLAVE io_thread; +Last_IO_Error = Relay log write failure: could not queue event from master +SET GLOBAL debug="-d,fault_injection_openning_index"; +SET GLOBAL debug=@old_debug; +include/stop_slave.inc +SET GLOBAL debug=@old_debug; +RESET SLAVE; +RESET MASTER; +include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt b/mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt new file mode 100644 index 00000000000..f8e46a44854 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt @@ -0,0 +1 @@ +--max_binlog_size=4096 diff --git a/mysql-test/suite/rpl/t/rpl_binlog_errors.test b/mysql-test/suite/rpl/t/rpl_binlog_errors.test new file mode 100644 index 00000000000..ae83659a38a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_errors.test @@ -0,0 +1,413 @@ +# BUG#46166: MYSQL_BIN_LOG::new_file_impl is not propagating error +# when generating new name. +# +# WHY +# === +# +# We want to check whether error is reported or not when +# new_file_impl fails (this may happen when rotation is not +# possible because there is some problem finding an +# unique filename). +# +# HOW +# === +# +# Test cases are documented inline. + +-- source include/master-slave.inc +-- source include/have_innodb.inc +-- source include/have_debug.inc + +-- echo ####################################################################### +-- echo ####################### PART 1: MASTER TESTS ########################## +-- echo ####################################################################### + + +### ACTION: stopping slave as it is not needed for the first part of +### the test + +-- connection slave +-- source include/stop_slave.inc +-- connection master + +call mtr.add_suppression("Can't generate a unique log-filename"); +call mtr.add_suppression("Writing one row to the row-based binary log failed.*"); +call mtr.add_suppression("Error writing file .*"); + +SET @old_debug= @@global.debug; + +### ACTION: create a large file (> 4096 bytes) that will be later used +### in LOAD DATA INFILE to check binlog errors in its vacinity +-- let $load_file= $MYSQLTEST_VARDIR/tmp/bug_46166.data +-- let $MYSQLD_DATADIR= `select @@datadir` +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SELECT repeat('x',8192) INTO OUTFILE '$load_file' + +### ACTION: create a small file (< 4096 bytes) that will be later used +### in LOAD DATA INFILE to check for absence of binlog errors +### when file loading this file does not force flushing and +### rotating the binary log +-- let $load_file2= $MYSQLTEST_VARDIR/tmp/bug_46166-2.data +-- let $MYSQLD_DATADIR= `select @@datadir` +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SELECT repeat('x',10) INTO OUTFILE '$load_file2' + +RESET MASTER; + +-- echo ###################### TEST #1 + +### ASSERTION: no problem flushing logs (should show two binlogs) +FLUSH LOGS; +-- echo # assert: must show two binlogs +-- source include/show_binary_logs.inc + +-- echo ###################### TEST #2 + +### ASSERTION: check that FLUSH LOGS actually fails and reports +### failure back to the user if find_uniq_filename fails +### (should show just one binlog) + +RESET MASTER; +SET GLOBAL debug="+d,error_unique_log_filename"; +-- error ER_NO_UNIQUE_LOGFILE +FLUSH LOGS; +-- echo # assert: must show one binlog +-- source include/show_binary_logs.inc + +### ACTION: clean up and move to next test +SET GLOBAL debug=""; +RESET MASTER; + +-- echo ###################### TEST #3 + +### ACTION: create some tables (t1, t2, t4) and insert some values in +### table t1 +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a TEXT) Engine=InnoDB; +CREATE TABLE t4 (a TEXT); +INSERT INTO t1 VALUES (1); +RESET MASTER; + +### ASSERTION: we force rotation of the binary log because it exceeds +### the max_binlog_size option (should show two binary +### logs) + +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t2 + +# shows two binary logs +-- echo # assert: must show two binlog +-- source include/show_binary_logs.inc + +# clean up the table and the binlog to be used in next part of test +SET GLOBAL debug="-d,error_unique_log_filename"; +DELETE FROM t2; +RESET MASTER; + +-- echo ###################### TEST #4 + +### ASSERTION: load the big file into a transactional table and check +### that it reports error. The table will contain the +### changes performed despite the fact that it reported an +### error. + +SET GLOBAL debug="+d,error_unique_log_filename"; +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- error ER_NO_UNIQUE_LOGFILE +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t2 + +# show table +-- echo # assert: must show one entry +SELECT count(*) FROM t2; + +# clean up the table and the binlog to be used in next part of test +SET GLOBAL debug="-d,error_unique_log_filename"; +DELETE FROM t2; +RESET MASTER; + +-- echo ###################### TEST #5 + +### ASSERTION: load the small file into a transactional table and +### check that it succeeds + +SET GLOBAL debug="+d,error_unique_log_filename"; +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA INFILE '$load_file2' INTO TABLE t2 + +# show table +-- echo # assert: must show one entry +SELECT count(*) FROM t2; + +# clean up the table and the binlog to be used in next part of test +SET GLOBAL debug="-d,error_unique_log_filename"; +DELETE FROM t2; +RESET MASTER; + +-- echo ###################### TEST #6 + +### ASSERTION: check that even if one is using a transactional table +### and explicit transactions (no autocommit) if rotation +### fails we get the error. Transaction is not rolledback +### because rotation happens after the commit. + +SET GLOBAL debug="+d,error_unique_log_filename"; +SET AUTOCOMMIT=0; +INSERT INTO t2 VALUES ('muse'); +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t2 +INSERT INTO t2 VALUES ('muse'); +-- error ER_NO_UNIQUE_LOGFILE +COMMIT; + +### ACTION: Show the contents of the table after the test +-- echo # assert: must show three entries +SELECT count(*) FROM t2; + +### ACTION: clean up and move to the next test +SET AUTOCOMMIT= 1; +SET GLOBAL debug="-d,error_unique_log_filename"; +DELETE FROM t2; +RESET MASTER; + +-- echo ###################### TEST #7 + +### ASSERTION: check that on a non-transactional table, if rotation +### fails then an error is reported and an incident event +### is written to the current binary log. + +SET GLOBAL debug="+d,error_unique_log_filename"; +SELECT count(*) FROM t4; +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- error ER_NO_UNIQUE_LOGFILE +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t4 + +-- echo # assert: must show 1 entry +SELECT count(*) FROM t4; + +-- echo ### check that the incident event is written to the current log +SET GLOBAL debug="-d,error_unique_log_filename"; +-- let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) +-- let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) + +# 53 is the size of the incident event, so we start from 22 bytes before the +# current position +-- let $binlog_start = `SELECT $binlog_start - 53` +FLUSH LOGS; +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR $binlog_start $binlog_file BINLOG_FILE +-- replace_column 2 # 4 # 5 # +-- eval SHOW BINLOG EVENTS IN '$binlog_file' FROM $binlog_start LIMIT 1 + +# clean up and move to next test +DELETE FROM t4; +RESET MASTER; + +-- echo ###################### TEST #8 + +### ASSERTION: check that statements end up in error but they succeed +### on changing the data. + +SET GLOBAL debug="+d,error_unique_log_filename"; +-- echo # must show 0 entries +SELECT count(*) FROM t4; +SELECT count(*) FROM t2; + +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- error ER_NO_UNIQUE_LOGFILE +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t4 +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- error ER_NO_UNIQUE_LOGFILE +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t2 +-- error ER_NO_UNIQUE_LOGFILE +INSERT INTO t2 VALUES ('aaa'), ('bbb'), ('ccc'); + +-- echo # INFO: Count(*) Before Offending DELETEs +-- echo # assert: must show 1 entry +SELECT count(*) FROM t4; +-- echo # assert: must show 4 entries +SELECT count(*) FROM t2; + +-- error ER_NO_UNIQUE_LOGFILE +DELETE FROM t4; +-- error ER_NO_UNIQUE_LOGFILE +DELETE FROM t2; + +-- echo # INFO: Count(*) After Offending DELETEs +-- echo # assert: must show zero entries +SELECT count(*) FROM t4; +SELECT count(*) FROM t2; + +# remove fault injection +SET GLOBAL debug="-d,error_unique_log_filename"; + +-- echo ###################### TEST #9 + +### ASSERTION: check that if we disable binlogging, then statements +### succeed. +SET GLOBAL debug="+d,error_unique_log_filename"; +SET SQL_LOG_BIN=0; +INSERT INTO t2 VALUES ('aaa'), ('bbb'), ('ccc'), ('ddd'); +INSERT INTO t4 VALUES ('eee'), ('fff'), ('ggg'), ('hhh'); +-- echo # assert: must show four entries +SELECT count(*) FROM t2; +SELECT count(*) FROM t4; +DELETE FROM t2; +DELETE FROM t4; +-- echo # assert: must show zero entries +SELECT count(*) FROM t2; +SELECT count(*) FROM t4; +SET SQL_LOG_BIN=1; +SET GLOBAL debug="-d,error_unique_log_filename"; + +-- echo ###################### TEST #10 + +### ASSERTION: check that error is reported if there is a failure +### while registering the index file and the binary log +### file or failure to write the rotate event. + +call mtr.add_suppression("MSYQL_BIN_LOG::open failed to sync the index file."); +call mtr.add_suppression("Could not open .*"); + +RESET MASTER; +SHOW WARNINGS; + +# +d,fault_injection_registering_index => injects fault on MYSQL_BIN_LOG::open +SET GLOBAL debug="+d,fault_injection_registering_index"; +-- error ER_CANT_OPEN_FILE +FLUSH LOGS; +SET GLOBAL debug="-d,fault_injection_registering_index"; + +-- error ER_NO_BINARY_LOGGING +SHOW BINARY LOGS; + +# issue some statements and check that they don't fail +CREATE TABLE t5 (a INT); +INSERT INTO t4 VALUES ('bbbbb'); +INSERT INTO t2 VALUES ('aaaaa'); +DELETE FROM t4; +DELETE FROM t2; +DROP TABLE t5; + +-- echo ###################### TEST #11 + +### ASSERTION: check that error is reported if there is a failure +### while opening the index file and the binary log file or +### failure to write the rotate event. + +# restart the server so that we have binlog again +--source include/restart_mysqld.inc + +# +d,fault_injection_openning_index => injects fault on MYSQL_BIN_LOG::open_index_file +SET GLOBAL debug="+d,fault_injection_openning_index"; +-- error ER_CANT_OPEN_FILE +FLUSH LOGS; +SET GLOBAL debug="-d,fault_injection_openning_index"; + +-- error ER_FLUSH_MASTER_BINLOG_CLOSED +RESET MASTER; + +# issue some statements and check that they don't fail +CREATE TABLE t5 (a INT); +INSERT INTO t4 VALUES ('bbbbb'); +INSERT INTO t2 VALUES ('aaaaa'); +DELETE FROM t4; +DELETE FROM t2; +DROP TABLE t5; + +# restart the server so that we have binlog again +-- source include/restart_mysqld.inc + +-- echo ###################### TEST #12 + +### ASSERTION: check that error is reported if there is a failure +### while writing the rotate event when creating a new log +### file. + +# +d,fault_injection_new_file_rotate_event => injects fault on MYSQL_BIN_LOG::MYSQL_BIN_LOG::new_file_impl +SET GLOBAL debug="+d,fault_injection_new_file_rotate_event"; +-- error ER_ERROR_ON_WRITE +FLUSH LOGS; +SET GLOBAL debug="-d,fault_injection_new_file_rotate_event"; + +-- error ER_FLUSH_MASTER_BINLOG_CLOSED +RESET MASTER; + +# issue some statements and check that they don't fail +CREATE TABLE t5 (a INT); +INSERT INTO t4 VALUES ('bbbbb'); +INSERT INTO t2 VALUES ('aaaaa'); +DELETE FROM t4; +DELETE FROM t2; +DROP TABLE t5; + +# restart the server so that we have binlog again +-- source include/restart_mysqld.inc + +## clean up +SET GLOBAL debug= @old_debug; +DROP TABLE t1, t2, t4; +RESET MASTER; + +# restart slave again +-- connection slave +-- source include/start_slave.inc +-- connection master + +-- echo ####################################################################### +-- echo ####################### PART 2: SLAVE TESTS ########################### +-- echo ####################################################################### + +### setup +-- connection master +# master-slave-reset starts the slave automatically +-- source include/master-slave-reset.inc +-- connection slave + +# slave suppressions + +call mtr.add_suppression("Slave I/O: Relay log write failure: could not queue event from master.*"); +call mtr.add_suppression("Error writing file .*"); +call mtr.add_suppression("Could not open .*"); +call mtr.add_suppression("MSYQL_BIN_LOG::open failed to sync the index file."); +call mtr.add_suppression("Can't generate a unique log-filename .*"); +-- echo ###################### TEST #13 + +#### ASSERTION: check against unique log filename error +-- let $io_thd_injection_fault_flag= error_unique_log_filename +-- let $slave_io_errno= 1595 +-- let $show_slave_io_error= 1 +-- source include/io_thd_fault_injection.inc + +-- echo ###################### TEST #14 + +#### ASSERTION: check against rotate failing +-- let $io_thd_injection_fault_flag= fault_injection_new_file_rotate_event +-- let $slave_io_errno= 1595 +-- let $show_slave_io_error= 1 +-- source include/io_thd_fault_injection.inc + +-- echo ###################### TEST #15 + +#### ASSERTION: check against relay log open failure +-- let $io_thd_injection_fault_flag= fault_injection_registering_index +-- let $slave_io_errno= 1595 +-- let $show_slave_io_error= 1 +-- source include/io_thd_fault_injection.inc + +-- echo ###################### TEST #16 + +#### ASSERTION: check against relay log index open failure +-- let $io_thd_injection_fault_flag= fault_injection_openning_index +-- let $slave_io_errno= 1595 +-- let $show_slave_io_error= 1 +-- source include/io_thd_fault_injection.inc + +### clean up +-- disable_warnings +-- source include/stop_slave.inc +-- enable_warnings +SET GLOBAL debug=@old_debug; +RESET SLAVE; +RESET MASTER; +-- source include/start_slave.inc +-- connection master +-- source include/master-slave-end.inc diff --git a/sql/handler.cc b/sql/handler.cc index 1525ca53bca..18381bc552c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1192,7 +1192,11 @@ int ha_commit_trans(THD *thd, bool all) error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0; DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE();); if (cookie) - tc_log->unlog(cookie, xid); + if(tc_log->unlog(cookie, xid)) + { + error= 2; + goto end; + } DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE();); end: if (rw_trans) diff --git a/sql/log.cc b/sql/log.cc index cff69b4cf51..46dcec2e2cd 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1871,10 +1871,11 @@ static int find_uniq_filename(char *name) *end='.'; length= (size_t) (end-start+1); - if (!(dir_info = my_dir(buff,MYF(MY_DONT_SORT)))) + if ((DBUG_EVALUATE_IF("error_unique_log_filename", 1, + !(dir_info = my_dir(buff,MYF(MY_DONT_SORT)))))) { // This shouldn't happen strmov(end,".1"); // use name+1 - DBUG_RETURN(0); + DBUG_RETURN(1); } file_info= dir_info->dir_entry; for (i=dir_info->number_off_files ; i-- ; file_info++) @@ -1888,8 +1889,7 @@ static int find_uniq_filename(char *name) my_dirend(dir_info); *end++='.'; - sprintf(end,"%06ld",max_found+1); - DBUG_RETURN(0); + DBUG_RETURN((sprintf(end,"%06ld",max_found+1) < 0)); } @@ -2101,6 +2101,8 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) { if (find_uniq_filename(new_name)) { + my_printf_error(ER_NO_UNIQUE_LOGFILE, ER(ER_NO_UNIQUE_LOGFILE), + MYF(ME_FATALERROR), log_name); sql_print_error(ER(ER_NO_UNIQUE_LOGFILE), log_name); return 1; } @@ -3066,7 +3068,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) if (!thd->slave_thread) need_start_event=1; if (!open_index_file(index_file_name, 0, FALSE)) - open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0, FALSE); + if ((error= open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0, FALSE))) + goto err; my_free((uchar*) save_name, MYF(0)); err: @@ -3728,17 +3731,23 @@ bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg) incapsulation 3) allows external access to the class without a lock (which is not possible with private new_file_without_locking method). + + @retval + nonzero - error */ -void MYSQL_BIN_LOG::new_file() +int MYSQL_BIN_LOG::new_file() { - new_file_impl(1); + return new_file_impl(1); } - -void MYSQL_BIN_LOG::new_file_without_locking() +/* + @retval + nonzero - error + */ +int MYSQL_BIN_LOG::new_file_without_locking() { - new_file_impl(0); + return new_file_impl(0); } @@ -3747,19 +3756,23 @@ void MYSQL_BIN_LOG::new_file_without_locking() @param need_lock Set to 1 if caller has not locked LOCK_log + @retval + nonzero - error + @note The new file name is stored last in the index file */ -void MYSQL_BIN_LOG::new_file_impl(bool need_lock) +int MYSQL_BIN_LOG::new_file_impl(bool need_lock) { - char new_name[FN_REFLEN], *new_name_ptr, *old_name; + int error= 0, close_on_error= FALSE; + char new_name[FN_REFLEN], *new_name_ptr, *old_name, *file_to_open; DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl"); if (!is_open()) { DBUG_PRINT("info",("log is closed")); - DBUG_VOID_RETURN; + DBUG_RETURN(error); } if (need_lock) @@ -3797,7 +3810,7 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock) We have to do this here and not in open as we want to store the new file name in the current binary log file. */ - if (generate_new_name(new_name, name)) + if ((error= generate_new_name(new_name, name))) goto end; new_name_ptr=new_name; @@ -3811,7 +3824,13 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock) */ Rotate_log_event r(new_name+dirname_length(new_name), 0, LOG_EVENT_OFFSET, is_relay_log ? Rotate_log_event::RELAY_LOG : 0); - r.write(&log_file); + if(DBUG_EVALUATE_IF("fault_injection_new_file_rotate_event", (error=close_on_error=TRUE), FALSE) || + (error= r.write(&log_file))) + { + close_on_error= TRUE; + my_printf_error(ER_ERROR_ON_WRITE, ER(ER_CANT_OPEN_FILE), MYF(ME_FATALERROR), name, errno); + goto end; + } bytes_written += r.data_written; } /* @@ -3839,17 +3858,56 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock) */ /* reopen index binlog file, BUG#34582 */ - if (!open_index_file(index_file_name, 0, FALSE)) - open(old_name, log_type, new_name_ptr, - io_cache_type, no_auto_events, max_size, 1, FALSE); + file_to_open= index_file_name; + error= open_index_file(index_file_name, 0, FALSE); + if (!error) + { + /* reopen the binary log file. */ + file_to_open= new_name_ptr; + error= open(old_name, log_type, new_name_ptr, io_cache_type, + no_auto_events, max_size, 1, FALSE); + } + + /* handle reopening errors */ + if (error) + { + my_printf_error(ER_CANT_OPEN_FILE, ER(ER_CANT_OPEN_FILE), + MYF(ME_FATALERROR), file_to_open, error); + close_on_error= TRUE; + } + my_free(old_name,MYF(0)); end: + + if (error && close_on_error /* rotate or reopen failed */) + { + /* + Close whatever was left opened. + + We are keeping the behavior as it exists today, ie, + we disable logging and move on (see: BUG#51014). + + TODO: as part of WL#1790 consider other approaches: + - kill mysql (safety); + - try multiple locations for opening a log file; + - switch server to protected/readonly mode + - ... + */ + close(LOG_CLOSE_INDEX); + sql_print_error("Could not open %s for logging (error %d). " + "Turning logging off for the whole duration " + "of the MySQL server process. To turn it on " + "again: fix the cause, shutdown the MySQL " + "server and restart it.", + new_name_ptr, errno); + } + if (need_lock) pthread_mutex_unlock(&LOCK_log); pthread_mutex_unlock(&LOCK_index); - DBUG_VOID_RETURN; + DBUG_RETURN(error); } @@ -3872,8 +3930,7 @@ bool MYSQL_BIN_LOG::append(Log_event* ev) bytes_written+= ev->data_written; DBUG_PRINT("info",("max_size: %lu",max_size)); if ((uint) my_b_append_tell(&log_file) > max_size) - new_file_without_locking(); - + error= new_file_without_locking(); err: pthread_mutex_unlock(&LOCK_log); signal_update(); // Safe as we don't call close @@ -3902,8 +3959,7 @@ bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...) } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint))); DBUG_PRINT("info",("max_size: %lu",max_size)); if ((uint) my_b_append_tell(&log_file) > max_size) - new_file_without_locking(); - + error= new_file_without_locking(); err: if (!error) signal_update(); @@ -4252,7 +4308,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd, if (!error) { signal_update(); - rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); + error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); } } @@ -4448,7 +4504,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) if (flush_and_sync()) goto err; signal_update(); - rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); + if ((error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED))) + goto err; + } error=0; @@ -4531,8 +4589,19 @@ bool general_log_write(THD *thd, enum enum_server_command command, return FALSE; } -void MYSQL_BIN_LOG::rotate_and_purge(uint flags) +/** + @note + If rotation fails, for instance the server was unable + to create a new log file, we still try to write an + incident event to the current log. + + @retval + nonzero - error +*/ +int MYSQL_BIN_LOG::rotate_and_purge(uint flags) { + int error= 0; + DBUG_ENTER("MYSQL_BIN_LOG::rotate_and_purge"); #ifdef HAVE_REPLICATION bool check_purge= false; #endif @@ -4541,26 +4610,38 @@ void MYSQL_BIN_LOG::rotate_and_purge(uint flags) if ((flags & RP_FORCE_ROTATE) || (my_b_tell(&log_file) >= (my_off_t) max_size)) { - new_file_without_locking(); + if ((error= new_file_without_locking())) + /** + Be conservative... There are possible lost events (eg, + failing to log the Execute_load_query_log_event + on a LOAD DATA while using a non-transactional + table)! + + We give it a shot and try to write an incident event anyway + to the current log. + */ + if (!write_incident(current_thd, FALSE)) + flush_and_sync(); + #ifdef HAVE_REPLICATION check_purge= true; #endif } if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED)) pthread_mutex_unlock(&LOCK_log); - #ifdef HAVE_REPLICATION /* NOTE: Run purge_logs wo/ holding LOCK_log as it otherwise will deadlock in ndbcluster_binlog_index_purge_file */ - if (check_purge && expire_logs_days) + if (!error && check_purge && expire_logs_days) { time_t purge_time= my_time(0) - expire_logs_days*24*60*60; if (purge_time >= 0) purge_logs_before_date(purge_time); } #endif + DBUG_RETURN(error); } uint MYSQL_BIN_LOG::next_file_id() @@ -4759,7 +4840,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock) if (!error && !(error= flush_and_sync())) { signal_update(); - rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); + error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); } pthread_mutex_unlock(&LOCK_log); } @@ -4871,7 +4952,8 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event, pthread_mutex_unlock(&LOCK_prep_xids); } else - rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); + if (rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED)) + goto err; } VOID(pthread_mutex_unlock(&LOCK_log)); @@ -5676,7 +5758,7 @@ int TC_LOG_MMAP::sync() cookie points directly to the memory where xid was logged. */ -void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid) +int TC_LOG_MMAP::unlog(ulong cookie, my_xid xid) { PAGE *p=pages+(cookie/tc_log_page_size); my_xid *x=(my_xid *)(data+cookie); @@ -5694,6 +5776,7 @@ void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid) if (p->waiters == 0) // the page is in pool and ready to rock pthread_cond_signal(&COND_pool); // ping ... for overflow() pthread_mutex_unlock(&p->lock); + return 0; } void TC_LOG_MMAP::close() @@ -5935,8 +6018,9 @@ int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid) DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle, TRUE)); } -void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid) +int TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid) { + DBUG_ENTER("TC_LOG_BINLOG::unlog"); pthread_mutex_lock(&LOCK_prep_xids); DBUG_ASSERT(prepared_xids > 0); if (--prepared_xids == 0) { @@ -5944,7 +6028,7 @@ void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid) pthread_cond_signal(&COND_prep_xids); } pthread_mutex_unlock(&LOCK_prep_xids); - rotate_and_purge(0); // as ::write() did not rotate + DBUG_RETURN(rotate_and_purge(0)); // as ::write() did not rotate } int TC_LOG_BINLOG::recover(IO_CACHE *log, Format_description_log_event *fdle) diff --git a/sql/log.h b/sql/log.h index 8f1ed7ee90c..2b0bc6111b3 100644 --- a/sql/log.h +++ b/sql/log.h @@ -39,7 +39,7 @@ class TC_LOG virtual int open(const char *opt_name)=0; virtual void close()=0; virtual int log_xid(THD *thd, my_xid xid)=0; - virtual void unlog(ulong cookie, my_xid xid)=0; + virtual int unlog(ulong cookie, my_xid xid)=0; }; class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging @@ -49,7 +49,7 @@ public: int open(const char *opt_name) { return 0; } void close() { } int log_xid(THD *thd, my_xid xid) { return 1; } - void unlog(ulong cookie, my_xid xid) { } + int unlog(ulong cookie, my_xid xid) { return 0; } }; #ifdef HAVE_MMAP @@ -94,7 +94,7 @@ class TC_LOG_MMAP: public TC_LOG int open(const char *opt_name); void close(); int log_xid(THD *thd, my_xid xid); - void unlog(ulong cookie, my_xid xid); + int unlog(ulong cookie, my_xid xid); int recover(); private: @@ -283,8 +283,8 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG new_file() is locking. new_file_without_locking() does not acquire LOCK_log. */ - void new_file_without_locking(); - void new_file_impl(bool need_lock); + int new_file_without_locking(); + int new_file_impl(bool need_lock); public: MYSQL_LOG::generate_name; @@ -314,7 +314,7 @@ public: int open(const char *opt_name); void close(); int log_xid(THD *thd, my_xid xid); - void unlog(ulong cookie, my_xid xid); + int unlog(ulong cookie, my_xid xid); int recover(IO_CACHE *log, Format_description_log_event *fdle); #if !defined(MYSQL_CLIENT) int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event); @@ -354,7 +354,7 @@ public: bool open_index_file(const char *index_file_name_arg, const char *log_name, bool need_mutex); /* Use this to start writing a new log file */ - void new_file(); + int new_file(); void reset_gathered_updates(THD *thd); bool write(Log_event* event_info); // binary log write @@ -379,7 +379,7 @@ public: void make_log_name(char* buf, const char* log_ident); bool is_active(const char* log_file_name); int update_log_index(LOG_INFO* linfo, bool need_update_threads); - void rotate_and_purge(uint flags); + int rotate_and_purge(uint flags); bool flush_and_sync(); int purge_logs(const char *to_log, bool included, bool need_mutex, bool need_update_threads, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 709a49b2036..526133c20c6 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1063,7 +1063,7 @@ uint cached_table_definitions(void); void kill_mysql(void); void close_connection(THD *thd, uint errcode, bool lock); bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, - bool *write_to_binlog); + int *write_to_binlog); #ifndef NO_EMBEDDED_ACCESS_CHECKS bool check_access(THD *thd, ulong access, const char *db, ulong *save_priv, bool no_grant, bool no_errors, bool schema_db); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3a33d06fb01..1a3a0886c1f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2839,7 +2839,7 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) case SIGHUP: if (!abort_loop) { - bool not_used; + int not_used; mysql_print_status(); // Print some debug info reload_acl_and_cache((THD*) 0, (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST | diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc index 43f4e7d849d..b797621d696 100644 --- a/sql/rpl_injector.cc +++ b/sql/rpl_injector.cc @@ -229,8 +229,7 @@ int injector::record_incident(THD *thd, Incident incident) Incident_log_event ev(thd, incident); if (int error= mysql_bin_log.write(&ev)) return error; - mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); - return 0; + return mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); } int injector::record_incident(THD *thd, Incident incident, LEX_STRING const message) @@ -238,6 +237,5 @@ int injector::record_incident(THD *thd, Incident incident, LEX_STRING const mess Incident_log_event ev(thd, incident, message); if (int error= mysql_bin_log.write(&ev)) return error; - mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); - return 0; + return mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); } diff --git a/sql/slave.cc b/sql/slave.cc index 644aade517c..96319de5427 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3398,8 +3398,7 @@ static int process_io_rotate(Master_info *mi, Rotate_log_event *rev) Rotate the relay log makes binlog format detection easier (at next slave start or mysqlbinlog) */ - rotate_relay_log(mi); /* will take the right mutexes */ - DBUG_RETURN(0); + DBUG_RETURN(rotate_relay_log(mi) /* will take the right mutexes */); } /* @@ -4482,10 +4481,11 @@ err: is void). */ -void rotate_relay_log(Master_info* mi) +int rotate_relay_log(Master_info* mi) { DBUG_ENTER("rotate_relay_log"); Relay_log_info* rli= &mi->rli; + int error= 0; /* We don't lock rli->run_lock. This would lead to deadlocks. */ pthread_mutex_lock(&mi->run_lock); @@ -4501,7 +4501,8 @@ void rotate_relay_log(Master_info* mi) } /* If the relay log is closed, new_file() will do nothing. */ - rli->relay_log.new_file(); + if ((error= rli->relay_log.new_file())) + goto end; /* We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately @@ -4519,7 +4520,7 @@ void rotate_relay_log(Master_info* mi) rli->relay_log.harvest_bytes_written(&rli->log_space_total); end: pthread_mutex_unlock(&mi->run_lock); - DBUG_VOID_RETURN; + DBUG_RETURN(error); } diff --git a/sql/slave.h b/sql/slave.h index f356d28b626..da14b3ab4b0 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -189,7 +189,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, const char** errmsg); void set_slave_thread_options(THD* thd); void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli); -void rotate_relay_log(Master_info* mi); +int rotate_relay_log(Master_info* mi); int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli); pthread_handler_t handle_slave_io(void *arg); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 4b68f2a3821..f2aedf5d0aa 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -567,6 +567,13 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, transactional_table, errcode); } + + /* + Flushing the IO CACHE while writing the execute load query log event + may result in error (for instance, because the max_binlog_size has been + reached, and rotation of the binary log failed). + */ + error= error || mysql_bin_log.get_log_file()->error; } if (error) goto err; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7cf64134d70..c81bd36cfad 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1474,7 +1474,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif case COM_REFRESH: { - bool not_used; + int not_used; status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]); ulong options= (ulong) (uchar) packet[0]; if (check_global_access(thd,RELOAD_ACL)) @@ -3227,7 +3227,11 @@ end_with_restore_list: { Incident_log_event ev(thd, incident); (void) mysql_bin_log.write(&ev); /* error is ignored */ - mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); + if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE)) + { + res= 1; + break; + } } DBUG_PRINT("debug", ("Just after generate_incident()")); } @@ -4051,7 +4055,7 @@ end_with_restore_list: lex->no_write_to_binlog= 1; case SQLCOM_FLUSH: { - bool write_to_binlog; + int write_to_binlog; if (check_global_access(thd,RELOAD_ACL)) goto error; @@ -4068,12 +4072,22 @@ end_with_restore_list: /* Presumably, RESET and binlog writing doesn't require synchronization */ - if (!lex->no_write_to_binlog && write_to_binlog) + + if (write_to_binlog > 0) // we should write + { + if (!lex->no_write_to_binlog) + res= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + } else if (write_to_binlog < 0) { - if ((res= write_bin_log(thd, FALSE, thd->query(), thd->query_length()))) - break; - } - my_ok(thd); + /* + We should not write, but rather report error because + reload_acl_and_cache binlog interactions failed + */ + res= 1; + } + + if (!res) + my_ok(thd); } break; @@ -6862,7 +6876,10 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List *using_fields, @param thd Thread handler (can be NULL!) @param options What should be reset/reloaded (tables, privileges, slave...) @param tables Tables to flush (if any) - @param write_to_binlog True if we can write to the binlog. + @param write_to_binlog < 0 if there was an error while interacting with the binary log inside + reload_acl_and_cache, + 0 if we should not write to the binary log, + > 0 if we can write to the binlog. @note Depending on 'options', it may be very bad to write the query to the binlog (e.g. FLUSH SLAVE); this is a @@ -6876,11 +6893,11 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List *using_fields, */ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, - bool *write_to_binlog) + int *write_to_binlog) { bool result=0; select_errors=0; /* Write if more errors */ - bool tmp_write_to_binlog= 1; + int tmp_write_to_binlog= *write_to_binlog= 1; DBUG_ASSERT(!thd || !thd->in_sub_stmt); @@ -6943,12 +6960,16 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, tmp_write_to_binlog= 0; if( mysql_bin_log.is_open() ) { - mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); + if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE)) + *write_to_binlog= -1; } #ifdef HAVE_REPLICATION + int rotate_error= 0; pthread_mutex_lock(&LOCK_active_mi); - rotate_relay_log(active_mi); + rotate_error= rotate_relay_log(active_mi); pthread_mutex_unlock(&LOCK_active_mi); + if (rotate_error) + *write_to_binlog= -1; #endif /* flush slow and general logs */ @@ -7059,7 +7080,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, #endif if (options & REFRESH_USER_RESOURCES) reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */ - *write_to_binlog= tmp_write_to_binlog; + if (*write_to_binlog != -1) + *write_to_binlog= tmp_write_to_binlog; /* If the query was killed then this function must fail. */ From c8310653b4a9a804576fac3afab75448fca1d1b5 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Wed, 1 Dec 2010 12:25:31 +0530 Subject: [PATCH 045/110] Additional fix for bug#54899 Fixing the testcase to use the database name as connected_db instead of 'test' database. --- mysql-test/r/mysql.result | 18 ++++++++---------- mysql-test/t/mysql.test | 29 ++++++++++++++--------------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index cc3f94528f7..f4298cc7a4c 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -294,16 +294,14 @@ Tables_in_test # Checking --one-database option with non_existent_db # specified with USE command # -SHOW TABLES IN test; -Tables_in_test -table_in_test -DROP DATABASE test; +CREATE DATABASE connected_db; +SHOW TABLES IN connected_db; +Tables_in_connected_db +table_in_connected_db -CREATE DATABASE test; -SHOW TABLES IN test; -Tables_in_test -table_in_test -DROP DATABASE test; -CREATE DATABASE test; +SHOW TABLES IN connected_db; +Tables_in_connected_db +table_in_connected_db +DROP DATABASE connected_db; End of tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 5e26e0b7ef5..2dcc77a16c2 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -523,35 +523,34 @@ SHOW TABLES IN test; --echo # specified with USE command --echo # -# CASE 1 : When 'test' database exists and passed at commandline. +# CASE 1 : When 'connected_db' database exists and passed at commandline. --write_file $MYSQLTEST_VARDIR/tmp/one_db_1.sql -CREATE TABLE `table_in_test`(i INT); +CREATE TABLE `table_in_connected_db`(i INT); USE non_existent_db; # Following statement should be filtered out. CREATE TABLE `table_in_non_existent_db`(i INT); EOF -# CASE 2 : When 'test' database exists but dropped and recreated in load file. +# CASE 2 : When 'connected_db' database exists but dropped and recreated in +# load file. --write_file $MYSQLTEST_VARDIR/tmp/one_db_2.sql -DROP DATABASE test; -CREATE DATABASE test; +DROP DATABASE connected_db; +CREATE DATABASE connected_db; USE non_existent_db; # Following statements should be filtered out. CREATE TABLE `table_in_non_existent_db`(i INT); -USE test; +USE connected_db; # Following statements should not be filtered out. -CREATE TABLE `table_in_test`(i INT); +CREATE TABLE `table_in_connected_db`(i INT); EOF ---exec $MYSQL --one-database test < $MYSQLTEST_VARDIR/tmp/one_db_1.sql -SHOW TABLES IN test; -DROP DATABASE test; +CREATE DATABASE connected_db; +--exec $MYSQL --one-database connected_db < $MYSQLTEST_VARDIR/tmp/one_db_1.sql +SHOW TABLES IN connected_db; --echo -CREATE DATABASE test; ---exec $MYSQL --one-database test < $MYSQLTEST_VARDIR/tmp/one_db_2.sql -SHOW TABLES IN test; -DROP DATABASE test; -CREATE DATABASE test; +--exec $MYSQL --one-database connected_db < $MYSQLTEST_VARDIR/tmp/one_db_2.sql +SHOW TABLES IN connected_db; +DROP DATABASE connected_db; --remove_file $MYSQLTEST_VARDIR/tmp/one_db_1.sql --remove_file $MYSQLTEST_VARDIR/tmp/one_db_2.sql From bb9efb59920582fad0455d941c792d6cfcc6d41b Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Wed, 1 Dec 2010 09:01:04 +0100 Subject: [PATCH 046/110] Bug#58621 perfschema.dml_ews_by_thread_by_event_name test failure This fix affects the test suite only. Before this fix, performance schema tests dml_*.test could fail with spurious failure, depending on the table content. This fix simplifies the SELECT tests in the dml_*.test scripts, to only verify that the SELECT operation passed the security checks and succeeded, which was the original intent of the test. Usage of --replace_column 1 # 2 # 3 # 4 # ... to discard the test output was replaced by a simpler and more maintainable --disable_result_log which also work for empty tables. --- .../suite/perfschema/r/dml_cond_instances.result | 3 --- .../perfschema/r/dml_events_waits_current.result | 3 --- .../perfschema/r/dml_events_waits_history.result | 7 ------- .../perfschema/r/dml_events_waits_history_long.result | 7 ------- .../suite/perfschema/r/dml_ews_by_instance.result | 11 ----------- .../r/dml_ews_by_thread_by_event_name.result | 3 --- .../perfschema/r/dml_ews_global_by_event_name.result | 3 --- .../suite/perfschema/r/dml_file_instances.result | 3 --- .../r/dml_file_summary_by_event_name.result | 3 --- .../perfschema/r/dml_file_summary_by_instance.result | 3 --- .../suite/perfschema/r/dml_mutex_instances.result | 3 --- .../suite/perfschema/r/dml_rwlock_instances.result | 3 --- mysql-test/suite/perfschema/r/dml_threads.result | 3 --- mysql-test/suite/perfschema/t/dml_cond_instances.test | 3 ++- .../suite/perfschema/t/dml_events_waits_current.test | 3 ++- .../suite/perfschema/t/dml_events_waits_history.test | 5 ++--- .../perfschema/t/dml_events_waits_history_long.test | 5 ++--- .../suite/perfschema/t/dml_ews_by_instance.test | 7 ++----- .../perfschema/t/dml_ews_by_thread_by_event_name.test | 3 ++- .../perfschema/t/dml_ews_global_by_event_name.test | 3 ++- mysql-test/suite/perfschema/t/dml_file_instances.test | 3 ++- .../perfschema/t/dml_file_summary_by_event_name.test | 3 ++- .../perfschema/t/dml_file_summary_by_instance.test | 3 ++- .../suite/perfschema/t/dml_mutex_instances.test | 3 ++- .../suite/perfschema/t/dml_rwlock_instances.test | 3 ++- mysql-test/suite/perfschema/t/dml_threads.test | 3 ++- 26 files changed, 26 insertions(+), 76 deletions(-) diff --git a/mysql-test/suite/perfschema/r/dml_cond_instances.result b/mysql-test/suite/perfschema/r/dml_cond_instances.result index 922effc59ae..285c32090af 100644 --- a/mysql-test/suite/perfschema/r/dml_cond_instances.result +++ b/mysql-test/suite/perfschema/r/dml_cond_instances.result @@ -1,9 +1,6 @@ select * from performance_schema.cond_instances limit 1; -NAME OBJECT_INSTANCE_BEGIN -# # select * from performance_schema.cond_instances where name='FOO'; -NAME OBJECT_INSTANCE_BEGIN 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' 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 9b0bcf7f876..122cfcce4a1 100644 --- a/mysql-test/suite/perfschema/r/dml_events_waits_current.result +++ b/mysql-test/suite/perfschema/r/dml_events_waits_current.result @@ -1,10 +1,7 @@ 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 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 set thread_id='1', event_id=1, event_name='FOO', timer_start=1, timer_end=2, timer_wait=3; 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 5fc95584c7f..199ccc1cfa5 100644 --- a/mysql-test/suite/perfschema/r/dml_events_waits_history.result +++ b/mysql-test/suite/perfschema/r/dml_events_waits_history.result @@ -1,18 +1,11 @@ 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 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 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 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 set thread_id='1', event_id=1, event_name='FOO', timer_start=1, timer_end=2, timer_wait=3; 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 2ce949b2228..773dcd3b1dc 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,18 +1,11 @@ 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 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 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 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 set thread_id='1', event_id=1, event_name='FOO', timer_start=1, timer_end=2, timer_wait=3; 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 0a745a2c38a..6ba37025d3b 100644 --- a/mysql-test/suite/perfschema/r/dml_ews_by_instance.result +++ b/mysql-test/suite/perfschema/r/dml_ews_by_instance.result @@ -1,26 +1,15 @@ 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 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 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 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 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 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 set event_name='FOO', object_instance_begin=0, count_star=1, sum_timer_wait=2, min_timer_wait=3, 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 c64bcdd40f6..a98acb5f536 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,10 +1,7 @@ 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 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 set event_name='FOO', thread_id=1, count_star=1, sum_timer_wait=2, min_timer_wait=3, 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 c59451922c5..159adbd8022 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,10 +1,7 @@ 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 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 set event_name='FOO', count_star=1, sum_timer_wait=2, min_timer_wait=3, avg_timer_wait=4, max_timer_wait=5; diff --git a/mysql-test/suite/perfschema/r/dml_file_instances.result b/mysql-test/suite/perfschema/r/dml_file_instances.result index 5a51a4ca018..4a8a7ac4d47 100644 --- a/mysql-test/suite/perfschema/r/dml_file_instances.result +++ b/mysql-test/suite/perfschema/r/dml_file_instances.result @@ -1,9 +1,6 @@ select * from performance_schema.file_instances limit 1; -FILE_NAME EVENT_NAME OPEN_COUNT -# # # select * from performance_schema.file_instances where file_name='FOO'; -FILE_NAME EVENT_NAME OPEN_COUNT 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' 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 97a196dbf19..a8a9fe852bb 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,10 +1,7 @@ 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 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 set event_name='FOO', count_read=1, count_write=2, sum_number_of_bytes_read=4, sum_number_of_bytes_write=5; 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 d85e23cb6f4..456d6e31173 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,10 +1,7 @@ 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 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 set event_name='FOO', count_read=1, count_write=2, sum_number_of_bytes_read=4, sum_number_of_bytes_write=5; diff --git a/mysql-test/suite/perfschema/r/dml_mutex_instances.result b/mysql-test/suite/perfschema/r/dml_mutex_instances.result index 1ea7311b149..665517c7227 100644 --- a/mysql-test/suite/perfschema/r/dml_mutex_instances.result +++ b/mysql-test/suite/perfschema/r/dml_mutex_instances.result @@ -1,9 +1,6 @@ select * from performance_schema.mutex_instances limit 1; -NAME OBJECT_INSTANCE_BEGIN LOCKED_BY_THREAD_ID -# # # select * from performance_schema.mutex_instances where name='FOO'; -NAME OBJECT_INSTANCE_BEGIN LOCKED_BY_THREAD_ID 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' diff --git a/mysql-test/suite/perfschema/r/dml_rwlock_instances.result b/mysql-test/suite/perfschema/r/dml_rwlock_instances.result index 964fa0fa46f..b072eea3955 100644 --- a/mysql-test/suite/perfschema/r/dml_rwlock_instances.result +++ b/mysql-test/suite/perfschema/r/dml_rwlock_instances.result @@ -1,9 +1,6 @@ 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 where name='FOO'; -NAME OBJECT_INSTANCE_BEGIN WRITE_LOCKED_BY_THREAD_ID READ_LOCKED_BY_COUNT 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' diff --git a/mysql-test/suite/perfschema/r/dml_threads.result b/mysql-test/suite/perfschema/r/dml_threads.result index 8c61521d091..b78d1934d1f 100644 --- a/mysql-test/suite/perfschema/r/dml_threads.result +++ b/mysql-test/suite/perfschema/r/dml_threads.result @@ -1,10 +1,7 @@ select * from performance_schema.threads where name like 'Thread/%' limit 1; -THREAD_ID PROCESSLIST_ID NAME -# # # select * from performance_schema.threads where name='FOO'; -THREAD_ID PROCESSLIST_ID NAME 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' diff --git a/mysql-test/suite/perfschema/t/dml_cond_instances.test b/mysql-test/suite/perfschema/t/dml_cond_instances.test index 528dae80dfa..e2773d15252 100644 --- a/mysql-test/suite/perfschema/t/dml_cond_instances.test +++ b/mysql-test/suite/perfschema/t/dml_cond_instances.test @@ -18,11 +18,12 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # +--disable_result_log select * from performance_schema.cond_instances limit 1; select * from performance_schema.cond_instances where name='FOO'; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.cond_instances 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 f82fac63df9..43a70618b4d 100644 --- a/mysql-test/suite/perfschema/t/dml_events_waits_current.test +++ b/mysql-test/suite/perfschema/t/dml_events_waits_current.test @@ -18,12 +18,13 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 12 # 14 # +--disable_result_log select * from performance_schema.events_waits_current where event_name like 'Wait/Synch/%' limit 1; select * from performance_schema.events_waits_current where event_name='FOO'; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.events_waits_current 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 865d261d7f9..51937a75f49 100644 --- a/mysql-test/suite/perfschema/t/dml_events_waits_history.test +++ b/mysql-test/suite/perfschema/t/dml_events_waits_history.test @@ -18,20 +18,19 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 12 # 14 # +--disable_result_log select * from performance_schema.events_waits_history where event_name like 'Wait/Synch/%' limit 1; 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 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 where event_name like 'Wait/Synch/%' order by timer_wait desc limit 1; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.events_waits_history 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 606e33b3e80..a7fc1937529 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 @@ -18,20 +18,19 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 12 # 14 # +--disable_result_log select * from performance_schema.events_waits_history_long where event_name like 'Wait/Synch/%' limit 1; 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 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 where event_name like 'Wait/Synch/%' order by timer_wait desc limit 1; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.events_waits_history_long 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 2e4ab9bcc74..2f25f842dcc 100644 --- a/mysql-test/suite/perfschema/t/dml_ews_by_instance.test +++ b/mysql-test/suite/perfschema/t/dml_ews_by_instance.test @@ -18,28 +18,25 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # +--disable_result_log 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 where event_name='FOO'; ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 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 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 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 where min_timer_wait > 0 order by count_star desc limit 1; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.events_waits_summary_by_instance 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 bdbee9a90c1..a1b41fdab42 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 @@ -18,12 +18,13 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # +--disable_result_log 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 where event_name='FOO'; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.events_waits_summary_by_thread_by_event_name 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 4f1b50bb7c0..bf311c7b470 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 @@ -18,12 +18,13 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # +--disable_result_log 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 where event_name='FOO'; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.events_waits_summary_global_by_event_name diff --git a/mysql-test/suite/perfschema/t/dml_file_instances.test b/mysql-test/suite/perfschema/t/dml_file_instances.test index f3a13eaee32..d7a1002b040 100644 --- a/mysql-test/suite/perfschema/t/dml_file_instances.test +++ b/mysql-test/suite/perfschema/t/dml_file_instances.test @@ -18,11 +18,12 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # +--disable_result_log select * from performance_schema.file_instances limit 1; select * from performance_schema.file_instances where file_name='FOO'; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.file_instances 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 f5e1f90e9c9..8060c4a4cbe 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 @@ -18,12 +18,13 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # 4 # 5 # +--disable_result_log 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 where event_name='FOO'; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.file_summary_by_event_name 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 2ac32b97f56..c24f57390a4 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 @@ -18,12 +18,13 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # +--disable_result_log select * from performance_schema.file_summary_by_instance where event_name like 'Wait/io/%' limit 1; select * from performance_schema.file_summary_by_instance where event_name='FOO'; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.file_summary_by_instance diff --git a/mysql-test/suite/perfschema/t/dml_mutex_instances.test b/mysql-test/suite/perfschema/t/dml_mutex_instances.test index c0bbd5276a0..1a48bd9d8ea 100644 --- a/mysql-test/suite/perfschema/t/dml_mutex_instances.test +++ b/mysql-test/suite/perfschema/t/dml_mutex_instances.test @@ -18,11 +18,12 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # +--disable_result_log select * from performance_schema.mutex_instances limit 1; select * from performance_schema.mutex_instances where name='FOO'; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.mutex_instances diff --git a/mysql-test/suite/perfschema/t/dml_rwlock_instances.test b/mysql-test/suite/perfschema/t/dml_rwlock_instances.test index c0fd89a8e75..b588502c996 100644 --- a/mysql-test/suite/perfschema/t/dml_rwlock_instances.test +++ b/mysql-test/suite/perfschema/t/dml_rwlock_instances.test @@ -18,11 +18,12 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # 4 # +--disable_result_log select * from performance_schema.rwlock_instances limit 1; select * from performance_schema.rwlock_instances where name='FOO'; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.rwlock_instances diff --git a/mysql-test/suite/perfschema/t/dml_threads.test b/mysql-test/suite/perfschema/t/dml_threads.test index e7188497061..6cb372e2c96 100644 --- a/mysql-test/suite/perfschema/t/dml_threads.test +++ b/mysql-test/suite/perfschema/t/dml_threads.test @@ -18,12 +18,13 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_column 1 # 2 # 3 # +--disable_result_log select * from performance_schema.threads where name like 'Thread/%' limit 1; select * from performance_schema.threads where name='FOO'; +--enable_result_log --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.threads From b12eb4a11a66c651f39ea73f3ce5f7e72738da59 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Wed, 1 Dec 2010 10:24:16 +0100 Subject: [PATCH 047/110] Bug#58512 Performance_schema.myisam_file_io fails sporadically in PB2 Before this fix, the test myisam_file_io executed: - (a) an update on setup_instrument to disable non myisam file io instruments - (b) a truncate on events_waits_history_long and later - (c) a select on events_waits_history_long Surprisingly, events that were supposed to be disabled in (a) and removed in (b) still were found in (c). This happened for events such as wait/io/file/innodb/innodb_data_file fil0fil.c: sync because the sync was started before (a) and completed after (b), and as a consequence was added in the performance schema history, as expected. Presence of these records in the history made the test fail. This fix makes the test script more robust to account for extra spill waits records in (c). --- mysql-test/suite/perfschema/r/myisam_file_io.result | 1 + mysql-test/suite/perfschema/t/myisam_file_io.test | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/mysql-test/suite/perfschema/r/myisam_file_io.result b/mysql-test/suite/perfschema/r/myisam_file_io.result index 287abd43d74..5cdcf6ac789 100644 --- a/mysql-test/suite/perfschema/r/myisam_file_io.result +++ b/mysql-test/suite/perfschema/r/myisam_file_io.result @@ -16,6 +16,7 @@ operation, number_of_bytes, substring(object_name, locate("no_index_tab", object_name)) as short_name from performance_schema.events_waits_history_long where operation not like "tell" + and event_name like "wait/io/file/myisam/%" order by thread_id, event_id; event_name short_source operation number_of_bytes short_name wait/io/file/myisam/kfile mi_create.c: create NULL no_index_tab.MYI diff --git a/mysql-test/suite/perfschema/t/myisam_file_io.test b/mysql-test/suite/perfschema/t/myisam_file_io.test index c2502b5895a..de9f6f48480 100644 --- a/mysql-test/suite/perfschema/t/myisam_file_io.test +++ b/mysql-test/suite/perfschema/t/myisam_file_io.test @@ -46,6 +46,13 @@ insert into no_index_tab set a = 'foo', b = 1; # Verification # Note that mi_create.c contains mysql_file_tell() calls in debug only, # so the result are filtered to remove 'tell'. +# Note that even after setting other instruments to enabled='NO' +# and truncating the events_waits_history_long table, +# some events -- that were already started but not completed -- +# for other instruments could still be added in the history. +# To protect against that, an extra where clause +# "and event_name like "wait/io/file/myisam/%" +# is added to the select to filter out the result. select event_name, left(source, locate(":", source)) as short_source, @@ -53,6 +60,7 @@ select event_name, substring(object_name, locate("no_index_tab", object_name)) as short_name from performance_schema.events_waits_history_long where operation not like "tell" + and event_name like "wait/io/file/myisam/%" order by thread_id, event_id; # In case of failures, this will tell if file io are lost. From 0c9c2112314239fec46e2a819806e5c07484c76a Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Wed, 1 Dec 2010 11:10:15 +0100 Subject: [PATCH 048/110] Bug#56618 Thread_ID is not assigned in ascending sequence (after disconnect) Before this fix, the test thread_cache failed with spurious failures. The test used: -- disconnect X -- connect Y while assuming that connection Y would reuse connection X slot in the thread cache. For this to happen, the disconnect X operation must be given enough time to complete, otherwise connect Y can be executed in the server before X actually finishes. This fix uses wait conditions to make the test execution more controlled, and more reproductible. --- .../suite/perfschema/r/thread_cache.result | 5 ++ .../suite/perfschema/t/thread_cache.test | 52 +++++++++++++++---- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/perfschema/r/thread_cache.result b/mysql-test/suite/perfschema/r/thread_cache.result index de4d19f9c64..f64cadc2705 100644 --- a/mysql-test/suite/perfschema/r/thread_cache.result +++ b/mysql-test/suite/perfschema/r/thread_cache.result @@ -1,3 +1,4 @@ +flush status; SET @saved_thread_cache_size = @@global.thread_cache_size; set global thread_cache_size = 0; show variables like "thread_cache_size"; @@ -32,3 +33,7 @@ select @thread_id_increment; @thread_id_increment 1 set global thread_cache_size = @saved_thread_cache_size; +show status like "performance_schema_thread%"; +Variable_name Value +Performance_schema_thread_classes_lost 0 +Performance_schema_thread_instances_lost 0 diff --git a/mysql-test/suite/perfschema/t/thread_cache.test b/mysql-test/suite/perfschema/t/thread_cache.test index 488b359cd34..e839552ed19 100644 --- a/mysql-test/suite/perfschema/t/thread_cache.test +++ b/mysql-test/suite/perfschema/t/thread_cache.test @@ -20,6 +20,8 @@ # Setup +flush status; + SET @saved_thread_cache_size = @@global.thread_cache_size; set global thread_cache_size = 0; @@ -40,7 +42,7 @@ let $con2_ID=`select connection_id()`; let $con2_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; -connection default; +--connection default --disable_query_log eval select ($con2_ID - $con1_ID) into @id_increment; @@ -52,7 +54,15 @@ select @id_increment; # Expect 1, THREAD_ID is incremented for each new connection select @thread_id_increment; -disconnect con2; +--disconnect con2 + +--connection default + +# Wait for the disconnect con2 to complete +let $wait_condition= + select count(*) = 2 from performance_schema.threads + where name like "thread/sql/one_connection"; +--source include/wait_condition.inc connect (con3, localhost, root, , ); @@ -61,10 +71,16 @@ let $con3_ID=`select connection_id()`; let $con3_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; -disconnect con3; -disconnect con1; +--disconnect con3 +--disconnect con1 -connection default; +--connection default + +# Wait for the disconnect con1 and con3 to complete +let $wait_condition= + select count(*) = 1 from performance_schema.threads + where name like "thread/sql/one_connection"; +--source include/wait_condition.inc --disable_query_log eval select ($con3_ID - $con2_ID) into @id_increment; @@ -92,7 +108,7 @@ let $con2_ID=`select connection_id()`; let $con2_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; -connection default; +--connection default --disable_query_log eval select ($con2_ID - $con1_ID) into @id_increment; @@ -102,7 +118,15 @@ eval select ($con2_THREAD_ID - $con1_THREAD_ID) into @thread_id_increment; select @id_increment; select @thread_id_increment; -disconnect con2; +--disconnect con2 + +--connection default + +# Wait for the disconnect con2 to complete +let $wait_condition= + select count(*) = 2 from performance_schema.threads + where name like "thread/sql/one_connection"; +--source include/wait_condition.inc connect (con3, localhost, root, , ); @@ -111,10 +135,16 @@ let $con3_ID=`select connection_id()`; let $con3_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; -disconnect con3; -disconnect con1; +--disconnect con3 +--disconnect con1 -connection default; +--connection default + +# Wait for the disconnect con1 and con3 to complete +let $wait_condition= + select count(*) = 1 from performance_schema.threads + where name like "thread/sql/one_connection"; +--source include/wait_condition.inc --disable_query_log eval select ($con3_ID - $con2_ID) into @id_increment; @@ -132,3 +162,5 @@ select @thread_id_increment; set global thread_cache_size = @saved_thread_cache_size; +show status like "performance_schema_thread%"; + From 9dca123d0281606872086a0101d94ce0ddcb91e4 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 1 Dec 2010 11:11:16 +0100 Subject: [PATCH 049/110] Bug #58092 Test "rpl_cross_version" has "copy_file" failing I am not fixing the test failure Adds printing of my_errno when commands fail, could hopefully help --- client/mysqltest.cc | 8 ++++---- mysql-test/r/mysqltest.result | 2 +- mysql-test/t/mysqltest.test | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b2fcb8fe39e..fbf4563163b 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1088,8 +1088,8 @@ void handle_command_error(struct st_command *command, uint error) int i; if (command->abort_on_error) - die("command \"%.*s\" failed with error %d", - command->first_word_len, command->query, error); + die("command \"%.*s\" failed with error %d. my_errno=%d", + command->first_word_len, command->query, error, my_errno); i= match_expected_error(command, error, NULL); @@ -1100,8 +1100,8 @@ void handle_command_error(struct st_command *command, uint error) DBUG_VOID_RETURN; } if (command->expected_errors.count > 0) - die("command \"%.*s\" failed with wrong error: %d", - command->first_word_len, command->query, error); + die("command \"%.*s\" failed with wrong error: %d. my_errno=%d", + command->first_word_len, command->query, error, my_errno); } else if (command->expected_errors.err[0].type == ERR_ERRNO && command->expected_errors.err[0].code.errnum != 0) diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 013728ebd01..c450369aa11 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -591,7 +591,7 @@ if things work as expected Some data for cat_file command of mysqltest -mysqltest: At line 1: command "cat_file" failed with error 1 +mysqltest: At line 1: command "cat_file" failed with error 1. (my_errno) mysqltest: At line 1: Missing required argument 'filename' to command 'file_exists' mysqltest: At line 1: Missing required argument 'from_file' to command 'copy_file' mysqltest: At line 1: Missing required argument 'to_file' to command 'copy_file' diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index fe04b8c19e0..b9197a7d4b9 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1936,6 +1936,7 @@ EOF cat_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +--replace_regex /my_errno=[0-9]*/(my_errno)/ --error 1 --exec echo "cat_file non_existing_file;" | $MYSQL_TEST 2>&1 From 033c6c394db89c3904a1bcf9ad050f1a29bf0d24 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Wed, 1 Dec 2010 13:06:41 +0100 Subject: [PATCH 050/110] Bug#53696 Performance schema engine violates the PSEA API by calling my_error() This is a code cleanup. The implementation of a storage engine (subclasses of handler) is not supposed to call my_error() directly inside the engine implementation, but only return error codes, and report errors later at the demand of the sql layer only (if needed), using handler::print_error(). This fix removes misplaced calls to my_error(), and provide an implementation of print_error() instead. Given that the sql layer implementation of create table, ha_create_table(), does not use print_error() but returns ER_CANT_CREATE_TABLE directly, the return code for create table statements using the performance schema has changed to ER_CANT_CREATE_TABLE. Adjusted the test suite accordingly. --- .../suite/perfschema/include/privilege.inc | 8 ++--- mysql-test/suite/perfschema/r/misc.result | 4 +-- .../suite/perfschema/r/privilege.result | 32 ++++++++--------- mysql-test/suite/perfschema/t/misc.test | 4 +-- storage/perfschema/ha_perfschema.cc | 35 ++++++++++++++++--- storage/perfschema/ha_perfschema.h | 5 ++- storage/perfschema/pfs_engine_table.cc | 5 --- storage/perfschema/table_setup_consumers.cc | 1 - storage/perfschema/table_setup_instruments.cc | 1 - storage/perfschema/table_setup_timers.cc | 1 - 10 files changed, 57 insertions(+), 39 deletions(-) diff --git a/mysql-test/suite/perfschema/include/privilege.inc b/mysql-test/suite/perfschema/include/privilege.inc index 3973c41b51b..f29ef65f519 100644 --- a/mysql-test/suite/perfschema/include/privilege.inc +++ b/mysql-test/suite/perfschema/include/privilege.inc @@ -100,16 +100,16 @@ create trigger performance_schema.bi_file_instances before insert on performance_schema.file_instances for each row begin end; ---error ER_WRONG_PERFSCHEMA_USAGE +--error ER_CANT_CREATE_TABLE create table test.t1(a int) engine=PERFORMANCE_SCHEMA; ---error ER_WRONG_PERFSCHEMA_USAGE +--error ER_CANT_CREATE_TABLE create table test.t1 like performance_schema.setup_instruments; ---error ER_WRONG_PERFSCHEMA_USAGE +--error ER_CANT_CREATE_TABLE create table test.t1 like performance_schema.events_waits_current; ---error ER_WRONG_PERFSCHEMA_USAGE +--error ER_CANT_CREATE_TABLE create table test.t1 like performance_schema.file_instances; --error ER_TABLEACCESS_DENIED_ERROR diff --git a/mysql-test/suite/perfschema/r/misc.result b/mysql-test/suite/perfschema/r/misc.result index 4e9b08e00ef..2f66f80ed75 100644 --- a/mysql-test/suite/perfschema/r/misc.result +++ b/mysql-test/suite/perfschema/r/misc.result @@ -6,9 +6,9 @@ AND EVENT_NAME IN WHERE NAME LIKE "wait/synch/%") LIMIT 1; create table test.t1(a int) engine=performance_schema; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table performance_schema.t1(a int); ERROR 42000: CREATE command denied to user 'root'@'localhost' for table 't1' drop table if exists test.ghost; diff --git a/mysql-test/suite/perfschema/r/privilege.result b/mysql-test/suite/perfschema/r/privilege.result index 61f5adac354..d1831c9c4be 100644 --- a/mysql-test/suite/perfschema/r/privilege.result +++ b/mysql-test/suite/perfschema/r/privilege.result @@ -152,13 +152,13 @@ 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. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.file_instances; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'setup_instruments' @@ -250,13 +250,13 @@ 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. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.file_instances; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'pfs_user_1'@'localhost' for table 'setup_instruments' @@ -348,13 +348,13 @@ 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. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.file_instances; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'pfs_user_2'@'localhost' for table 'setup_instruments' @@ -446,13 +446,13 @@ 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. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) create table test.t1 like performance_schema.file_instances; -ERROR HY000: Invalid performance_schema usage. +ERROR HY000: Can't create table 'test.t1' (errno: 131) insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'pfs_user_3'@'localhost' for table 'setup_instruments' diff --git a/mysql-test/suite/perfschema/t/misc.test b/mysql-test/suite/perfschema/t/misc.test index 72e891ca805..dee18f0fa21 100644 --- a/mysql-test/suite/perfschema/t/misc.test +++ b/mysql-test/suite/perfschema/t/misc.test @@ -38,14 +38,14 @@ LIMIT 1; # Bug#45088 Should not be able to create tables of engine PERFORMANCE_SCHEMA # ---error ER_WRONG_PERFSCHEMA_USAGE +--error ER_CANT_CREATE_TABLE create table test.t1(a int) engine=performance_schema; # # Bug#44897 Performance Schema: can create a ghost table in another database # ---error ER_WRONG_PERFSCHEMA_USAGE +--error ER_CANT_CREATE_TABLE create table test.t1 like performance_schema.events_waits_current; # diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc index 896117397a2..8e3486a4fa3 100644 --- a/storage/perfschema/ha_perfschema.cc +++ b/storage/perfschema/ha_perfschema.cc @@ -228,7 +228,6 @@ int ha_perfschema::write_row(uchar *buf) result= m_table_share->m_write_row(table, buf, table->field); else { - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); result= HA_ERR_WRONG_COMMAND; } @@ -339,7 +338,6 @@ int ha_perfschema::delete_all_rows(void) result= m_table_share->m_delete_all_rows(); else { - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); result= HA_ERR_WRONG_COMMAND; } DBUG_RETURN(result); @@ -370,7 +368,6 @@ int ha_perfschema::delete_table(const char *name) int ha_perfschema::rename_table(const char * from, const char * to) { DBUG_ENTER("ha_perfschema::rename_table "); - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -395,7 +392,37 @@ int ha_perfschema::create(const char *name, TABLE *table_arg, This is not a general purpose engine. Failure to CREATE TABLE is the expected result. */ - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } +void ha_perfschema::print_error(int error, myf errflag) +{ + switch (error) + { + case HA_ERR_TABLE_NEEDS_UPGRADE: + /* + The error message for ER_TABLE_NEEDS_UPGRADE refers to REPAIR table, + which does not apply to performance schema tables. + */ + my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0), + table_share->db.str, table_share->table_name.str); + break; + case HA_ERR_WRONG_COMMAND: + /* + The performance schema is not a general purpose storage engine, + some operations are not supported, by design. + We do not want to print "Command not supported", + which gives the impression that a command implementation is missing, + and that the failure should be considered a bug. + We print "Invalid performance_schema usage." instead, + to emphasise that the operation attempted is not meant to be legal, + and that the failure returned is indeed the expected result. + */ + my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); + break; + default: + handler::print_error(error, errflag); + break; + } +} + diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h index 1a0c16541be..c0ee0827dbc 100644 --- a/storage/perfschema/ha_perfschema.h +++ b/storage/perfschema/ha_perfschema.h @@ -100,9 +100,6 @@ public: double scan_time(void) { return 1.0; } - double read_time(ha_rows) - { return 1.0; } - int open(const char *name, int mode, uint test_if_locked); int close(void); @@ -149,6 +146,8 @@ public: return FALSE; } + virtual void print_error(int error, myf errflags); + private: /** MySQL lock */ THR_LOCK_DATA m_thr_lock; diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index 3b1959c98d2..cec068a686b 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -232,8 +232,6 @@ int PFS_engine_table::read_row(TABLE *table, */ if (! m_share_ptr->m_checked) { - my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0), - PERFORMANCE_SCHEMA_str.str, m_share_ptr->m_name.str); return HA_ERR_TABLE_NEEDS_UPGRADE; } @@ -279,8 +277,6 @@ int PFS_engine_table::update_row(TABLE *table, */ if (! m_share_ptr->m_checked) { - my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0), - PERFORMANCE_SCHEMA_str.str, m_share_ptr->m_name.str); return HA_ERR_TABLE_NEEDS_UPGRADE; } @@ -351,7 +347,6 @@ int PFS_engine_table::update_row_values(TABLE *, unsigned char *, Field **) { - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); return HA_ERR_WRONG_COMMAND; } diff --git a/storage/perfschema/table_setup_consumers.cc b/storage/perfschema/table_setup_consumers.cc index 5b39fd89a03..601e0483b14 100644 --- a/storage/perfschema/table_setup_consumers.cc +++ b/storage/perfschema/table_setup_consumers.cc @@ -192,7 +192,6 @@ int table_setup_consumers::update_row_values(TABLE *table, switch(f->field_index) { case 0: /* NAME */ - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); return HA_ERR_WRONG_COMMAND; case 1: /* ENABLED */ { diff --git a/storage/perfschema/table_setup_instruments.cc b/storage/perfschema/table_setup_instruments.cc index 310f859248b..480c0dbc13f 100644 --- a/storage/perfschema/table_setup_instruments.cc +++ b/storage/perfschema/table_setup_instruments.cc @@ -253,7 +253,6 @@ int table_setup_instruments::update_row_values(TABLE *table, switch(f->field_index) { case 0: /* NAME */ - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); return HA_ERR_WRONG_COMMAND; case 1: /* ENABLED */ value= (enum_yes_no) get_field_enum(f); diff --git a/storage/perfschema/table_setup_timers.cc b/storage/perfschema/table_setup_timers.cc index 24ec18dafb1..f8b1bfa4fe2 100644 --- a/storage/perfschema/table_setup_timers.cc +++ b/storage/perfschema/table_setup_timers.cc @@ -164,7 +164,6 @@ int table_setup_timers::update_row_values(TABLE *table, switch(f->field_index) { case 0: /* NAME */ - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); return HA_ERR_WRONG_COMMAND; case 1: /* TIMER_NAME */ value= get_field_enum(f); From d4f4d5489fc17adf42f22681b2485f3f15764ef8 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Wed, 1 Dec 2010 13:38:47 +0100 Subject: [PATCH 051/110] Updated build_mccge.sh to handle Open64 compiler, to remove autotools and a debug build bug fix --- BUILD/build_mccge.sh | 295 ++++++++++++++++++++++++++++++++----------- 1 file changed, 224 insertions(+), 71 deletions(-) diff --git a/BUILD/build_mccge.sh b/BUILD/build_mccge.sh index f29a2f1db34..004194961d5 100755 --- a/BUILD/build_mccge.sh +++ b/BUILD/build_mccge.sh @@ -42,9 +42,7 @@ cat < x86 and 32-bit binary x86_64 => x86 and 64 bit binary @@ -389,7 +406,8 @@ extended_usage() platforms supported by this script. The --fast option adds -mtune=cpu_arg to the C/C++ flags (provides - support for Nocona, K8, and other processors). + support for Nocona, K8, and other processors), this option is valid + when gcc is the compiler. Use of the --debug option adds -g to the C/C++ flags. @@ -397,10 +415,35 @@ extended_usage() by calling the script as follows: CC="/usr/local/bin/gcc" CXX="/usr/local/bin/gcc" BUILD/build_mccge.sh - FreeBSD/x86/gcc - --------------- - No flags are used. Instead, configure determines the proper flags to - use. + Feedback profiler on gcc + ------------------------ + Using gcc --generate-feedback=path causes the following flags to be added + to the compiler flags. + + --fprofile-generate + --fprofile-dir=path + + Using gcc with --use-feedback=path causes the following flags to be added + to the compiler flags. --fprofile-correction indicates MySQL is a multi- + threaded application and thus counters can be inconsistent with each other + and the compiler should take this into account. + + --fprofile-use + --fprofile-dir=path + --fprofile-correction + + Feedback compilation using Open64 + --------------------------------- + + Using Open64 with --generate-feedback=path causes the following flags to + be added to the compiler flags. + + -fb-create path/feedback + + Using Open64 with --use-feedback=path causes the following flags to be + added to the compiler flags. + + --fb-opt path/feedback Linux/x86+Itanium/gcc ------------- @@ -410,6 +453,9 @@ extended_usage() added to the C/C++ flags. (To build a 32-bit binary on a 64-bit CPU, use the --32 option as described previously.) + When gcc 4.5 is used and the user set --with-link-time-optimizer then + also --flto is added to compiler flags and linker flags. + Linux/x86+Itanium/icc ------------- Flags used: @@ -433,6 +479,19 @@ extended_usage() added to the C/C++ flags; this provides optimisations specific to Core 2 Duo. This is added only when the --fast flag is set. + Linux/x86/Open64 + ---------------- + For normal builds use -O3, when fast flag is set one also adds + --march=auto to generate optimized builds for the CPU used. If + --with-link-time-optimizer is set also -ipa is set. There is also + a special flag --with-mso which can be set to get --mso set which + activates optimisation for multi-core scalability. + + FreeBSD/x86/gcc + --------------- + No flags are used. Instead, configure determines the proper flags to + use. + Solaris/x86/gcc --------------- All builds on Solaris are by default 64-bit, so -m64 is always used in @@ -653,6 +712,9 @@ parse_compiler() forte | SunStudio | sunstudio ) compiler="forte" ;; + open64 | Open64 ) + compiler="open64" + ;; *) echo "Unknown compiler '$compiler'" exit 1 @@ -686,6 +748,15 @@ parse_options() --with-fast-mutexes) with_fast_mutexes="yes" ;; + --without-fast-mutexes) + with_fast_mutexes="no" + ;; + --without-perfschema) + with_perfschema="no" + ;; + --with-mso) + with_mso="yes" + ;; --use-tcmalloc) use_tcmalloc="yes" ;; @@ -693,6 +764,10 @@ parse_options() with_debug_flag="yes" fast_flag="no" ;; + --extra-debug-flag) + shift + extra_debug_flags="$extra_debug_flags -D$1" + ;; --debug) compile_debug_flag="yes" ;; @@ -712,6 +787,14 @@ parse_options() compiler=`get_key_value "$1"` parse_compiler ;; + --generate-feedback) + shift + GENERATE_FEEDBACK_PATH="$1" + ;; + --use-feedback) + shift + USE_FEEDBACK_PATH="$1" + ;; --cpu=*) cpu_type=`get_key_value "$1"` parse_cpu_type @@ -746,12 +829,6 @@ parse_options() --parallelism=*) parallelism=`get_key_value "$1"` ;; - --use-autotools) - use_autotools="yes" - ;; - --no-autotools) - use_autotools="no" - ;; --configure-only) just_configure="yes" ;; @@ -896,6 +973,9 @@ set_cpu_base() # init_configure_commands() { + path=`dirname $0` + cp $path/cmake_configure.sh $path/../configure + chmod +x $path/../configure cflags="$c_warnings $base_cflags $compiler_flags" cxxflags="$cxx_warnings $base_cxxflags $compiler_flags" configure="./configure $base_configs $with_flags" @@ -1084,6 +1164,7 @@ set_with_debug_flags() loc_debug_flags="-DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS " compiler_flags="$compiler_flags $loc_debug_flags" fi + compiler_flags="$compiler_flags $extra_debug_flags" fi } @@ -1105,7 +1186,7 @@ set_no_omit_frame_pointer_for_developers() # set_debug_flag() { - if test "x$compile_debug_flags" = "xyes" ; then + if test "x$compile_debug_flag" = "xyes" ; then compiler_flags="$compiler_flags -g" fi } @@ -1152,7 +1233,9 @@ set_base_configs() fi base_configs="$base_configs --with-pic" base_configs="$base_configs --with-csv-storage-engine" - base_configs="$base_configs --with-perfschema" + if test "x$with_perfschema" != "xno" ; then + base_configs="$base_configs --with-perfschema" + fi } # @@ -1251,6 +1334,19 @@ set_gcc_special_options() fi } +# +# If we discover a Core 2 Duo architecture and we have enabled the fast +# flag, we enable a compile especially optimised for Core 2 Duo. This +# feature is currently available on Intel's icc compiler only. +# +set_icc_special_options() +{ + if test "x$fast_flag" = "xyes" && test "x$cpu_arg" = "xcore2" && \ + test "x$compiler" = "xicc" ; then + compiler_flags="$compiler_flags -xT" + fi +} + set_cc_and_cxx_for_gcc() { if test "x$CC" = "x" ; then @@ -1271,6 +1367,16 @@ set_cc_and_cxx_for_icc() fi } +set_cc_and_cxx_for_open64() +{ + if test "x$CC" = "x" ; then + CC="opencc -static-libgcc -fno-exceptions" + fi + if test "x$CXX" = "x" ; then + CXX="openCC -static-libgcc -fno-exceptions" + fi +} + set_cc_and_cxx_for_forte() { if test "x$CC" = "x" ; then @@ -1281,19 +1387,6 @@ set_cc_and_cxx_for_forte() fi } -# -# If we discover a Core 2 Duo architecture and we have enabled the fast -# flag, we enable a compile especially optimised for Core 2 Duo. This -# feature is currently available on Intel's icc compiler only. -# -set_icc_special_options() -{ - if test "x$fast_flag" = "xyes" && test "x$cpu_arg" = "xcore2" && \ - test "x$compiler" = "xicc" ; then - compiler_flags="$compiler_flags -xT" - fi -} - # # FreeBSD Section # @@ -1357,12 +1450,45 @@ get_gcc_version() fi } +# +# Link time optimizer (interprocedural optimizations) for Open64 +# +check_for_open64_link_time_optimizer() +{ + if test "x$with_link_time_optimizer" = "xyes" ; then + compiler_flags="$compiler_flags -ipa" + LDFLAGS="$LDFLAGS -ipa" + fi +} + +# +# Link time optimizer (interprocedural optimizations) for icc +# +check_for_icc_link_time_optimizer() +{ + if test "x$with_link_time_optimizer" = "xyes" ; then + compiler_flags="$compiler_flags -ipo" + LDFLAGS="$LDFLAGS -ipo" + fi +} + +# +# Link time optimizer (interprocedural optimizations) for forte +# +check_for_forte_link_time_optimizer() +{ + if test "x$with_link_time_optimizer" = "xyes" ; then + compiler_flags="$compiler_flags -ipo" + LDFLAGS="$LDFLAGS -ipo" + fi +} + # # Link Time Optimizer in GCC (LTO) uses a parameter -flto # which was added to GCC 4.5, if --with-link-time-optimizer # is set then use this feature # -check_for_link_time_optimizer() +check_for_gcc_link_time_optimizer() { get_gcc_version if test "$gcc_version" -ge 405 && \ @@ -1371,11 +1497,37 @@ check_for_link_time_optimizer() LDFLAGS="$LDFLAGS -flto" fi } + +set_feedback_for_gcc() +{ + if test "x$GENERATE_FEEDBACK_PATH" != "x" ; then + compiler_flags="$compiler_flags -fprofile-generate" + compiler_flags="$compiler_flags -fprofile-dir=$GENERATE_FEEDBACK_PATH" + elif test "x$USE_FEEDBACK_PATH" != "x" ; then + compiler_flags="$compiler_flags -fprofile-use" + compiler_flags="$compiler_flags -fprofile-correction" + compiler_flags="$compiler_flags -fprofile-dir=$USE_FEEDBACK_PATH" + fi +} + +set_feedback_for_open64() +{ + if test "x$GENERATE_FEEDBACK_PATH" != "x" ; then + compiler_flags="$compiler_flags --fb-create=$GENERATE_FEEDBACK_PATH/feedback" + elif test "x$USE_FEEDBACK_PATH" != "x" ; then + compiler_flags="$compiler_flags --fb-opt=$USE_FEEDBACK_PATH/feedback" + fi +} + # # Linux Section # set_linux_configs() { +# Default to use --with-fast-mutexes on Linux + if test "x$with_fast_mutexes" = "x" ; then + base_configs="$base_configs --with-fast-mutexes" + fi if test "x$cpu_base_type" != "xx86" && \ test "x$cpu_base_type" != "xitanium" ; then usage "Only x86 and Itanium CPUs supported for Linux" @@ -1392,19 +1544,14 @@ set_linux_configs() if test "x$fast_flag" != "xno" ; then if test "x$fast_flag" = "xyes" ; then compiler_flags="$compiler_flags -O3" - check_for_link_time_optimizer + check_for_gcc_link_time_optimizer else - compiler_flags="$compiler_flags -O2" + compiler_flags="$compiler_flags -O3" fi else compiler_flags="$compiler_flags -O0" fi - check_64_bits - if test "x$m64" = "xyes" ; then - compiler_flags="$compiler_flags -m64" - else - compiler_flags="$compiler_flags -m32" - fi + set_feedback_for_gcc # configure will set proper compiler flags for gcc on Linux elif test "x$compiler" = "xicc" ; then compiler_flags="$compiler_flags -mp -restrict" @@ -1414,16 +1561,36 @@ set_linux_configs() fi if test "x$fast_flag" != "xno" ; then compiler_flags="$compiler_flags -O3 -unroll2 -ip" - if test "x$fast_flag" = "xyes" && \ - test "x$with_link_time_optimizer" = "xyes" ; then - compiler_flags="$compiler_flags -ipo" - LDFLAGS="$LDFLAGS -ipo" + if test "x$fast_flag" = "xyes" ; then + check_for_icc_link_time_optimizer fi fi + elif test "x$compiler" = "xopen64" ; then + set_cc_and_cxx_for_open64 + if test "x$fast_flag" != "xno" ; then + if test "x$fast_flag" = "xyes" ; then + compiler_flags="$compiler_flags -O3" +# Generate code specific for the machine you run on + compiler_flags="$compiler_flags -march=auto" + check_for_open64_link_time_optimizer + if test "x$with_mso" = "xyes" ; then + compiler_flags="$compiler_flags -mso" + fi + else + compiler_flags="$compiler_flags -O3" + fi + fi + set_feedback_for_open64 else - usage "Only gcc and icc compilers supported for Linux" + usage "Only gcc,icc and Open64 compilers supported for Linux" exit 1 fi + check_64_bits + if test "x$m64" = "xyes" ; then + compiler_flags="$compiler_flags -m64" + else + compiler_flags="$compiler_flags -m32" + fi } # @@ -1475,7 +1642,7 @@ set_solaris_configs() if test "x$fast_flag" = "xyes" ; then LDFLAGS="$LDFLAGS -O3" compiler_flags="$compiler_flags -O3" - check_for_link_time_optimizer + check_for_gcc_link_time_optimizer else if test "x$fast_flag" = "xgeneric" ; then LDFLAGS="$LDFLAGS -O2" @@ -1498,10 +1665,7 @@ set_solaris_configs() if test "x$fast_flag" = "xyes" ; then compiler_flags="$compiler_flags -xtarget=native" compiler_flags="$compiler_flags -xunroll=3" - if test "x$with_link_time_optimizer" = "xyes" ; then - compiler_flags="$compiler_flags -xipo" - LDFLAGS="$LDFLAGS -xipo" - fi + check_for_forte_link_time_optimizer else compiler_flags="$compiler_flags -xtarget=generic" fi @@ -1612,17 +1776,6 @@ set_default_package() fi } -set_autotool_flags() -{ - if test "x$use_autotools" = "x" ; then - if test "x$developer_flag" = "xno" ; then - use_autotools="no" - else - use_autotools="yes" - fi - fi -} - set_defaults_based_on_environment() { if test ! -z "$MYSQL_DEVELOPER" ; then @@ -1674,25 +1827,28 @@ base_cxxflags= base_configs= debug_flags= cxxflags= +extra_debug_flags= m64= explicit_size_set= datadir= commands= -use_autotools= engine_configs= ASFLAGS= LDFLAGS= use_tcmalloc= without_comment="yes" with_fast_mutexes= +with_perfschema="yes" with_link_time_optimizer= +with_mso= gcc_version="0" +generate_feedback_path= +use_feedback_path= set_defaults_based_on_environment parse_options "$@" -set_autotool_flags set_default_package set -e @@ -1793,9 +1949,6 @@ set_ccache_usage # Set up commands variable from variables prepared for base # configurations, compiler flags, and warnings flags. # -if test "x$use_autotools" = "xyes" ; then - init_auto_commands -fi init_configure_commands if test "x$just_configure" != "xyes" ; then @@ -1806,8 +1959,8 @@ fi # The commands variable now contains the entire command to be run for # the build; we either execute it, or merely print it out. # -if test "x$just_print" = "xyes" ; then - echo "$commands" -else +echo "Running command:" +echo "$commands" +if test "x$just_print" != "xyes" ; then eval "set -x; $commands" fi From 91a4a8aba6b087c908e3d29ccfbb7ff97d19dea7 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Wed, 1 Dec 2010 13:54:50 +0100 Subject: [PATCH 052/110] BUG#58246: INSTALL PLUGIN not secure & crashable When installing plugins, there is a missing check for slash (/) in the path on Windows. Note that on Windows, both / and \ can be used to separate directories. This patch fixes the issue by: - Adding a FN_DIRSEP symbol for all platforms consisting of a string of legal directory separators. - Adding a charset-aware version of strcspn(). - Adding a check_valid_path() function that uses my_strcspn() to check if any FN_DIRSEP character is in the supplied string. - Using the check_valid_path() function in sql_plugin.cc and sql_udf.cc (which means replacing the existing test there). --- include/config-netware.h | 1 + include/config-win.h | 1 + include/m_ctype.h | 2 + include/my_global.h | 1 + mysql-test/r/plugin_not_embedded.result | 2 + mysql-test/t/plugin_not_embedded.test | 11 ++++ sql/sql_plugin.cc | 23 ++++++++- sql/sql_plugin.h | 1 + sql/sql_udf.cc | 12 +---- strings/my_strchr.c | 67 +++++++++++++++++++++++-- 10 files changed, 105 insertions(+), 16 deletions(-) diff --git a/include/config-netware.h b/include/config-netware.h index 4b9e1437170..156b1eff0e4 100644 --- a/include/config-netware.h +++ b/include/config-netware.h @@ -122,6 +122,7 @@ extern "C" { #define CANT_DELETE_OPEN_FILES 1 #define FN_LIBCHAR '\\' +#define FN_DIRSEP "/\\" /* Valid directory separators */ #define FN_ROOTDIR "\\" #define FN_DEVCHAR ':' diff --git a/include/config-win.h b/include/config-win.h index da9b1fc00c3..f802bbbbad8 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -332,6 +332,7 @@ inline ulonglong double2ulonglong(double d) /* File name handling */ #define FN_LIBCHAR '\\' +#define FN_DIRSEP "/\\" /* Valid directory separators */ #define FN_ROOTDIR "\\" #define FN_DEVCHAR ':' #define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */ diff --git a/include/m_ctype.h b/include/m_ctype.h index 451c8db549b..47a3a09f531 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -464,6 +464,8 @@ extern my_bool my_parse_charset_xml(const char *bug, size_t len, int (*add)(CHARSET_INFO *cs)); extern char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end, pchar c); +extern size_t my_strcspn(CHARSET_INFO *cs, const char *str, const char *end, + const char *accept); my_bool my_propagate_simple(CHARSET_INFO *cs, const uchar *str, size_t len); my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, size_t len); diff --git a/include/my_global.h b/include/my_global.h index ec22a57329b..ac5d72249f2 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -758,6 +758,7 @@ typedef SOCKET_SIZE_TYPE size_socket; #ifndef FN_LIBCHAR #define FN_LIBCHAR '/' +#define FN_DIRSEP "/" /* Valid directory separators */ #define FN_ROOTDIR "/" #endif #define MY_NFILE 64 /* This is only used to save filenames */ diff --git a/mysql-test/r/plugin_not_embedded.result b/mysql-test/r/plugin_not_embedded.result index 82cfe7b23b8..27553366660 100644 --- a/mysql-test/r/plugin_not_embedded.result +++ b/mysql-test/r/plugin_not_embedded.result @@ -8,3 +8,5 @@ ERROR 42000: DELETE command denied to user 'bug51770'@'localhost' for table 'plu GRANT DELETE ON mysql.plugin TO bug51770@localhost; UNINSTALL PLUGIN example; DROP USER bug51770@localhost; +INSTALL PLUGIN example SONAME '../ha_example.so'; +ERROR HY000: No paths allowed for shared library diff --git a/mysql-test/t/plugin_not_embedded.test b/mysql-test/t/plugin_not_embedded.test index 15aff548c29..486b42e99d9 100644 --- a/mysql-test/t/plugin_not_embedded.test +++ b/mysql-test/t/plugin_not_embedded.test @@ -18,3 +18,14 @@ UNINSTALL PLUGIN example; disconnect con1; connection default; DROP USER bug51770@localhost; + +# +# BUG#58246: INSTALL PLUGIN not secure & crashable +# +# The bug consisted of not recognizing / on Windows, so checking / on +# all platforms should cover this case. + +let $path = `select CONCAT_WS('/', '..', $HA_EXAMPLE_SO)`; +--error ER_UDF_NO_PATHS +eval INSTALL PLUGIN example SONAME '$path'; + diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index e0fc88c3068..d8423fd153b 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -231,6 +231,26 @@ extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists); #endif /* EMBEDDED_LIBRARY */ +/** + Check if the provided path is valid in the sense that it does cause + a relative reference outside the directory. + + @note Currently, this function only check if there are any + characters in FN_DIRSEP in the string, but it might change in the + future. + + @code + check_valid_path("../foo.so") -> true + check_valid_path("foo.so") -> false + @endcode + */ +bool check_valid_path(const char *path, size_t len) +{ + size_t prefix= my_strcspn(files_charset_info, path, path + len, FN_DIRSEP); + return prefix < len; +} + + /**************************************************************************** Value type thunks, allows the C world to play in the C++ world ****************************************************************************/ @@ -354,13 +374,14 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) struct st_plugin_dl *tmp, plugin_dl; void *sym; DBUG_ENTER("plugin_dl_add"); + DBUG_PRINT("enter", ("dl->str: '%s', dl->length: %d", dl->str, dl->length)); plugin_dir_len= strlen(opt_plugin_dir); /* Ensure that the dll doesn't have a path. This is done to ensure that only approved libraries from the plugin directory are used (to make this even remotely secure). */ - if (my_strchr(files_charset_info, dl->str, dl->str + dl->length, FN_LIBCHAR) || + if (check_valid_path(dl->str, dl->length) || check_string_char_length((LEX_STRING *) dl, "", NAME_CHAR_LEN, system_charset_info, 1) || plugin_dir_len + dl->length + 1 >= FN_REFLEN) diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index 004d0d5abb7..72984865807 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -131,6 +131,7 @@ extern bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name); extern bool plugin_register_builtin(struct st_mysql_plugin *plugin); extern void plugin_thdvar_init(THD *thd); extern void plugin_thdvar_cleanup(THD *thd); +extern bool check_valid_path(const char *path, size_t length); typedef my_bool (plugin_foreach_func)(THD *thd, plugin_ref plugin, diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index d455a66c4f2..1d5335f0652 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -173,10 +173,7 @@ void udf_init() On windows we must check both FN_LIBCHAR and '/'. */ - if (my_strchr(files_charset_info, dl_name, - dl_name + strlen(dl_name), FN_LIBCHAR) || - IF_WIN(my_strchr(files_charset_info, dl_name, - dl_name + strlen(dl_name), '/'), 0) || + if (check_valid_path(dl_name, strlen(dl_name)) || check_string_char_length(&name, "", NAME_CHAR_LEN, system_charset_info, 1)) { @@ -416,13 +413,8 @@ int mysql_create_function(THD *thd,udf_func *udf) Ensure that the .dll doesn't have a path This is done to ensure that only approved dll from the system directories are used (to make this even remotely secure). - - On windows we must check both FN_LIBCHAR and '/'. */ - if (my_strchr(files_charset_info, udf->dl, - udf->dl + strlen(udf->dl), FN_LIBCHAR) || - IF_WIN(my_strchr(files_charset_info, udf->dl, - udf->dl + strlen(udf->dl), '/'), 0)) + if (check_valid_path(udf->dl, strlen(udf->dl))) { my_message(ER_UDF_NO_PATHS, ER(ER_UDF_NO_PATHS), MYF(0)); DBUG_RETURN(1); diff --git a/strings/my_strchr.c b/strings/my_strchr.c index 6724bf39ff2..08fa51ba17a 100644 --- a/strings/my_strchr.c +++ b/strings/my_strchr.c @@ -13,6 +13,45 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include +#include "m_string.h" +#include "m_ctype.h" + +#define NEQ(A, B) ((A) != (B)) +#define EQU(A, B) ((A) == (B)) + +/** + Macro for the body of the string scanning. + + @param CS The character set of the string + @param STR Pointer to beginning of string + @param END Pointer to one-after-end of string + @param ACC Pointer to beginning of accept (or reject) string + @param LEN Length of accept (or reject) string + @param CMP is a function-like for doing the comparison of two characters. + */ + +#define SCAN_STRING(CS, STR, END, ACC, LEN, CMP) \ + do { \ + uint mbl; \ + const char *ptr_str, *ptr_acc; \ + const char *acc_end= (ACC) + (LEN); \ + for (ptr_str= (STR) ; ptr_str < (END) ; ptr_str+= mbl) \ + { \ + mbl= my_mbcharlen((CS), *(uchar*)ptr_str); \ + if (mbl < 2) \ + { \ + DBUG_ASSERT(mbl == 1); \ + for (ptr_acc= (ACC) ; ptr_acc < acc_end ; ++ptr_acc) \ + if (CMP(*ptr_acc, *ptr_str)) \ + goto end; \ + } \ + } \ +end: \ + return (size_t) (ptr_str - (STR)); \ + } while (0) + + /* my_strchr(cs, str, end, c) returns a pointer to the first place in str where c (1-byte character) occurs, or NULL if c does not occur @@ -21,11 +60,6 @@ frequently. */ -#include -#include "m_string.h" -#include "m_ctype.h" - - char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end, pchar c) { @@ -45,3 +79,26 @@ char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end, return(0); } +/** + Calculate the length of the initial segment of 'str' which consists + entirely of characters not in 'reject'. + + @note The reject string points to single-byte characters so it is + only possible to find the first occurrence of a single-byte + character. Multi-byte characters in 'str' are treated as not + matching any character in the reject string. + + @todo should be moved to CHARSET_INFO if it's going to be called + frequently. + + @internal The implementation builds on the assumption that 'str' is long, + while 'reject' is short. So it compares each character in string + with the characters in 'reject' in a tight loop over the characters + in 'reject'. +*/ + +size_t my_strcspn(CHARSET_INFO *cs, const char *str, const char *str_end, + const char *reject) +{ + SCAN_STRING(cs, str, str_end, reject, strlen(reject), EQU); +} From 45f6f933d16722391002a0bd358456dc6386e8ee Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 1 Dec 2010 15:56:46 +0300 Subject: [PATCH 053/110] BUG#58205 - Valgrind failure in fn_format when called from archive_discover Fixed buffer underrun in cleanup_dirname(). Also fixed that original (unencoded) database and table names were used to discover archive tables. --- mysql-test/r/archive.result | 6 ++++++ mysql-test/t/archive.test | 8 ++++++++ mysys/mf_pack.c | 3 ++- storage/archive/ha_archive.cc | 3 ++- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 028c8b32f87..231b7acb5b4 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12801,3 +12801,9 @@ t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 DROP TABLE t1; +# +# BUG#58205 - Valgrind failure in fn_format when called from +# archive_discover +# +CREATE TABLE `a/../`(a INT) ENGINE=ARCHIVE; +DROP TABLE `a/../`; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index c3a080612a9..ce5047124a2 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1722,3 +1722,11 @@ INSERT INTO t1 VALUES (2); SELECT * FROM t1 ORDER BY a; SHOW CREATE TABLE t1; DROP TABLE t1; + +--echo # +--echo # BUG#58205 - Valgrind failure in fn_format when called from +--echo # archive_discover +--echo # +CREATE TABLE `a/../`(a INT) ENGINE=ARCHIVE; +remove_file $MYSQLD_DATADIR/test/a@002f@002e@002e@002f.frm; +DROP TABLE `a/../`; diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index c6e6a3a429e..a9482187138 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -192,7 +192,8 @@ size_t cleanup_dirname(register char *to, const char *from) end_parentdir=pos; while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */ pos--; - if (pos[1] == FN_HOMELIB || memcmp(pos,parent,length) == 0) + if (pos[1] == FN_HOMELIB || + (pos > start && memcmp(pos, parent, length) == 0)) { /* Don't remove ~user/ */ pos=strmov(end_parentdir+1,parent); *pos=FN_LIBCHAR; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index c24fbc21f94..fe167318743 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -20,6 +20,7 @@ #include "sql_priv.h" #include "probes_mysql.h" #include "sql_class.h" // SSV +#include "sql_table.h" #include #include "ha_archive.h" @@ -256,7 +257,7 @@ int archive_discover(handlerton *hton, THD* thd, const char *db, char *frm_ptr; MY_STAT file_stat; - fn_format(az_file, name, db, ARZ, MY_REPLACE_EXT | MY_UNPACK_FILENAME); + build_table_filename(az_file, sizeof(az_file) - 1, db, name, ARZ, 0); if (!(my_stat(az_file, &file_stat, MYF(0)))) goto err; From f3c6e6ffd6f78d298a133594a4dfe6635d302ffc Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Wed, 1 Dec 2010 22:47:40 +0100 Subject: [PATCH 054/110] Bug#58147: ALTER TABLE w/ TRUNCATE PARTITION fails but the statement is written to binlog TRUNCATE PARTITION was written to the binlog even if it failed before calling any partition's truncate function. Solved by adding an argument to truncate_partition, to flag if it should be written to the binlog or not. It should be written to the binlog when a call to any partitions truncate function is done. --- mysql-test/r/partition_binlog.result | 56 ++++++++++++++++++++++++++++ mysql-test/t/partition_binlog.test | 42 +++++++++++++++++++++ sql/ha_partition.cc | 7 +++- sql/ha_partition.h | 2 +- sql/sql_partition_admin.cc | 11 ++++-- 5 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 mysql-test/r/partition_binlog.result create mode 100644 mysql-test/t/partition_binlog.test diff --git a/mysql-test/r/partition_binlog.result b/mysql-test/r/partition_binlog.result new file mode 100644 index 00000000000..8b449371d0e --- /dev/null +++ b/mysql-test/r/partition_binlog.result @@ -0,0 +1,56 @@ +DROP TABLE IF EXISTS t1; +# +# Bug#58147: ALTER TABLE w/ TRUNCATE PARTITION fails +# but the statement is written to binlog +# +CREATE TABLE t1(id INT) +PARTITION BY RANGE (id) +(PARTITION p0 VALUES LESS THAN (100), +PARTITION pmax VALUES LESS THAN (MAXVALUE)); +INSERT INTO t1 VALUES (1), (10), (100), (1000); +ALTER TABLE t1 TRUNCATE PARTITION p1; +ERROR HY000: Incorrect partition name +ALTER TABLE t1 DROP PARTITION p1; +ERROR HY000: Error in list of partitions to DROP +# No error returned, output in table format instead: +ALTER TABLE t1 ANALYZE PARTITION p1; +Table Op Msg_type Msg_text +test.t1 analyze error Error in list of partitions to test.t1 +ALTER TABLE t1 CHECK PARTITION p1; +Table Op Msg_type Msg_text +test.t1 check error Error in list of partitions to test.t1 +ALTER TABLE t1 OPTIMIZE PARTITION p1; +Table Op Msg_type Msg_text +test.t1 optimize error Error in list of partitions to test.t1 +ALTER TABLE t1 REPAIR PARTITION p1; +Table Op Msg_type Msg_text +test.t1 repair error Error in list of partitions to test.t1 +ALTER TABLE t1 ANALYZE PARTITION p0; +Table Op Msg_type Msg_text +test.t1 analyze status OK +ALTER TABLE t1 CHECK PARTITION p0; +Table Op Msg_type Msg_text +test.t1 check status OK +ALTER TABLE t1 OPTIMIZE PARTITION p0; +Table Op Msg_type Msg_text +test.t1 optimize status OK +ALTER TABLE t1 REPAIR PARTITION p0; +Table Op Msg_type Msg_text +test.t1 repair status OK +ALTER TABLE t1 TRUNCATE PARTITION p0; +ALTER TABLE t1 DROP PARTITION p0; +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`; CREATE TABLE t1(id INT) +PARTITION BY RANGE (id) +(PARTITION p0 VALUES LESS THAN (100), +PARTITION pmax VALUES LESS THAN (MAXVALUE)) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1), (10), (100), (1000) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # use `test`; ALTER TABLE t1 ANALYZE PARTITION p0 +master-bin.000001 # Query # # use `test`; ALTER TABLE t1 OPTIMIZE PARTITION p0 +master-bin.000001 # Query # # use `test`; ALTER TABLE t1 REPAIR PARTITION p0 +master-bin.000001 # Query # # use `test`; ALTER TABLE t1 TRUNCATE PARTITION p0 +master-bin.000001 # Query # # use `test`; ALTER TABLE t1 DROP PARTITION p0 +DROP TABLE t1; diff --git a/mysql-test/t/partition_binlog.test b/mysql-test/t/partition_binlog.test new file mode 100644 index 00000000000..432cdc922d6 --- /dev/null +++ b/mysql-test/t/partition_binlog.test @@ -0,0 +1,42 @@ +--source include/have_log_bin.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +--echo # +--echo # Bug#58147: ALTER TABLE w/ TRUNCATE PARTITION fails +--echo # but the statement is written to binlog +--echo # + +--let $binlog_file=query_get_value(SHOW MASTER STATUS, File, 1) +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) + +CREATE TABLE t1(id INT) +PARTITION BY RANGE (id) +(PARTITION p0 VALUES LESS THAN (100), + PARTITION pmax VALUES LESS THAN (MAXVALUE)); + +INSERT INTO t1 VALUES (1), (10), (100), (1000); + +--error ER_WRONG_PARTITION_NAME +ALTER TABLE t1 TRUNCATE PARTITION p1; +--error ER_DROP_PARTITION_NON_EXISTENT +ALTER TABLE t1 DROP PARTITION p1; + +--echo # No error returned, output in table format instead: +ALTER TABLE t1 ANALYZE PARTITION p1; +ALTER TABLE t1 CHECK PARTITION p1; +ALTER TABLE t1 OPTIMIZE PARTITION p1; +ALTER TABLE t1 REPAIR PARTITION p1; + +ALTER TABLE t1 ANALYZE PARTITION p0; +ALTER TABLE t1 CHECK PARTITION p0; +ALTER TABLE t1 OPTIMIZE PARTITION p0; +ALTER TABLE t1 REPAIR PARTITION p0; +ALTER TABLE t1 TRUNCATE PARTITION p0; +ALTER TABLE t1 DROP PARTITION p0; + +--source include/show_binlog_events.inc + +DROP TABLE t1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index f4e240e5cc1..be9c4c13ff4 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3428,7 +3428,7 @@ int ha_partition::truncate() ALTER TABLE t TRUNCATE PARTITION ... */ -int ha_partition::truncate_partition(Alter_info *alter_info) +int ha_partition::truncate_partition(Alter_info *alter_info, bool *to_binlog) { int error= 0; List_iterator part_it(m_part_info->partitions); @@ -3440,6 +3440,9 @@ int ha_partition::truncate_partition(Alter_info *alter_info) PART_ADMIN); DBUG_ENTER("ha_partition::truncate_partition"); + /* Only binlog when it starts any call to the partitions handlers */ + *to_binlog= false; + /* TRUNCATE also means resetting auto_increment. Hence, reset it so that it will be initialized again at the next use. @@ -3453,6 +3456,8 @@ int ha_partition::truncate_partition(Alter_info *alter_info) (!(alter_info->flags & ALTER_ALL_PARTITION))) DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND); + *to_binlog= true; + do { partition_element *part_elem= part_it++; diff --git a/sql/ha_partition.h b/sql/ha_partition.h index f1abc0cefe2..cb91dcba6a3 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -362,7 +362,7 @@ public: @remark This method is a partitioning-specific hook and thus not a member of the general SE API. */ - int truncate_partition(Alter_info *); + int truncate_partition(Alter_info *, bool *to_binlog); virtual bool is_fatal_error(int error, uint flags) { diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index 8f6ab5803d7..716f57b15e8 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -110,6 +110,7 @@ bool Alter_table_truncate_partition_statement::execute(THD *thd) ha_partition *partition; ulong timeout= thd->variables.lock_wait_timeout; TABLE_LIST *first_table= thd->lex->select_lex.table_list.first; + bool to_binlog; DBUG_ENTER("Alter_table_truncate_partition_statement::execute"); /* @@ -161,16 +162,18 @@ bool Alter_table_truncate_partition_statement::execute(THD *thd) partition= (ha_partition *) first_table->table->file; /* Invoke the handler method responsible for truncating the partition. */ - if ((error= partition->truncate_partition(&thd->lex->alter_info))) + if ((error= partition->truncate_partition(&thd->lex->alter_info, + &to_binlog))) first_table->table->file->print_error(error, MYF(0)); /* All effects of a truncate operation are committed even if the operation fails. Thus, the query must be written to the binary - log. The only exception is a unimplemented truncate method. Also, - it is logged in statement format, regardless of the binlog format. + log. The exception is a unimplemented truncate method or failure + before any call to handler::truncate() is done. + Also, it is logged in statement format, regardless of the binlog format. */ - if (error != HA_ERR_WRONG_COMMAND) + if (error != HA_ERR_WRONG_COMMAND && to_binlog) error|= write_bin_log(thd, !error, thd->query(), thd->query_length()); /* From 71c32129bd7932f79bcf443f48669526e3992818 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Thu, 2 Dec 2010 08:14:43 +0100 Subject: [PATCH 055/110] BUG#58246 post-push fix broken DBG build. --- sql/sql_plugin.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index d8423fd153b..03a729258ca 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -374,7 +374,8 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) struct st_plugin_dl *tmp, plugin_dl; void *sym; DBUG_ENTER("plugin_dl_add"); - DBUG_PRINT("enter", ("dl->str: '%s', dl->length: %d", dl->str, dl->length)); + DBUG_PRINT("enter", ("dl->str: '%s', dl->length: %d", + dl->str, (int) dl->length)); plugin_dir_len= strlen(opt_plugin_dir); /* Ensure that the dll doesn't have a path. From afb8f0f88287cf3852d680f3c0e4f2e8ff102e76 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Thu, 2 Dec 2010 09:13:31 +0100 Subject: [PATCH 056/110] BUG#58246: INSTALL PLUGIN not secure & crashable Fixing test case that fails on Windows because .dll is used. --- mysql-test/t/plugin_not_embedded.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/plugin_not_embedded.test b/mysql-test/t/plugin_not_embedded.test index 486b42e99d9..40024efcaad 100644 --- a/mysql-test/t/plugin_not_embedded.test +++ b/mysql-test/t/plugin_not_embedded.test @@ -26,6 +26,7 @@ DROP USER bug51770@localhost; # all platforms should cover this case. let $path = `select CONCAT_WS('/', '..', $HA_EXAMPLE_SO)`; +--replace_regex /\.dll/.so/ --error ER_UDF_NO_PATHS eval INSTALL PLUGIN example SONAME '$path'; From 2bd4a70833c29fe02f46f7bf08bac0806e4525d0 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Thu, 2 Dec 2010 09:18:47 +0100 Subject: [PATCH 057/110] Bug #58246: INSTALL PLUGIN not secure & crashable Adding symbol FN_DIRSEP to Windows as well. --- include/my_global.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/my_global.h b/include/my_global.h index 155450e07de..a411ab8a118 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -611,6 +611,7 @@ typedef SOCKET_SIZE_TYPE size_socket; #ifdef _WIN32 #define FN_LIBCHAR '\\' #define FN_LIBCHAR2 '/' +#define FN_DIRSEP "/\\" /* Valid directory separators */ #define FN_ROOTDIR "\\" #define FN_DEVCHAR ':' #define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */ From 5618a20e1026cece0cf183e4b21edbaeb3891390 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 3 Dec 2010 14:05:33 +0100 Subject: [PATCH 058/110] post-push fix for test to work on row-based-replication --- mysql-test/r/partition_binlog.result | 7 ------- mysql-test/t/partition_binlog.test | 6 +++--- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/partition_binlog.result b/mysql-test/r/partition_binlog.result index 8b449371d0e..c8fa02c4b99 100644 --- a/mysql-test/r/partition_binlog.result +++ b/mysql-test/r/partition_binlog.result @@ -41,13 +41,6 @@ ALTER TABLE t1 TRUNCATE PARTITION p0; ALTER TABLE t1 DROP PARTITION p0; 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`; CREATE TABLE t1(id INT) -PARTITION BY RANGE (id) -(PARTITION p0 VALUES LESS THAN (100), -PARTITION pmax VALUES LESS THAN (MAXVALUE)) -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1), (10), (100), (1000) -master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; ALTER TABLE t1 ANALYZE PARTITION p0 master-bin.000001 # Query # # use `test`; ALTER TABLE t1 OPTIMIZE PARTITION p0 master-bin.000001 # Query # # use `test`; ALTER TABLE t1 REPAIR PARTITION p0 diff --git a/mysql-test/t/partition_binlog.test b/mysql-test/t/partition_binlog.test index 432cdc922d6..c1f618b794f 100644 --- a/mysql-test/t/partition_binlog.test +++ b/mysql-test/t/partition_binlog.test @@ -9,9 +9,6 @@ DROP TABLE IF EXISTS t1; --echo # but the statement is written to binlog --echo # ---let $binlog_file=query_get_value(SHOW MASTER STATUS, File, 1) ---let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) - CREATE TABLE t1(id INT) PARTITION BY RANGE (id) (PARTITION p0 VALUES LESS THAN (100), @@ -19,6 +16,9 @@ PARTITION BY RANGE (id) INSERT INTO t1 VALUES (1), (10), (100), (1000); +--let $binlog_file=query_get_value(SHOW MASTER STATUS, File, 1) +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) + --error ER_WRONG_PARTITION_NAME ALTER TABLE t1 TRUNCATE PARTITION p1; --error ER_DROP_PARTITION_NON_EXISTENT From 1dd333a29ee3cb0a5f4332604e47fb540b70c8d2 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 3 Dec 2010 14:43:49 +0000 Subject: [PATCH 059/110] Add --parallel=auto to collection files which don't currently have it. --- mysql-test/collections/default.weekly | 4 ++-- mysql-test/collections/test-bt | 20 ++++++++++---------- mysql-test/collections/test-bt-debug | 2 +- mysql-test/collections/test-bt-fast | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/mysql-test/collections/default.weekly b/mysql-test/collections/default.weekly index 33d13d8edfd..a064641784a 100644 --- a/mysql-test/collections/default.weekly +++ b/mysql-test/collections/default.weekly @@ -1,2 +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 large_tests.alter_table main.alter_table-big main.archive-big main.count_distinct3 main.create-big main.events_stress main.events_time_zone main.information_schema-big main.log_tables-big main.merge-big main.mysqlbinlog_row_big main.read_many_rows_innodb main.ssl-big main.sum_distinct-big main.type_newdecimal-big main.variables-big parts.part_supported_sql_func_innodb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_ndb parts.partition_alter1_2_innodb parts.partition_alter1_2_ndb parts.partition_alter2_1_1_innodb parts.partition_alter2_1_2_innodb parts.partition_alter2_2_2_innodb parts.partition_alter4_innodb rpl_ndb.rpl_truncate_7ndb_2 +perl mysql-test-run.pl --timer --force --parallel=auto --comment=1st --experimental=collections/default.experimental 1st +perl mysql-test-run.pl --timer --force --parallel=auto --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 large_tests.alter_table main.alter_table-big main.archive-big main.count_distinct3 main.create-big main.events_stress main.events_time_zone main.information_schema-big main.log_tables-big main.merge-big main.mysqlbinlog_row_big main.read_many_rows_innodb main.ssl-big main.sum_distinct-big main.type_newdecimal-big main.variables-big parts.part_supported_sql_func_innodb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_ndb parts.partition_alter1_2_innodb parts.partition_alter1_2_ndb parts.partition_alter2_1_1_innodb parts.partition_alter2_1_2_innodb parts.partition_alter2_2_2_innodb parts.partition_alter4_innodb rpl_ndb.rpl_truncate_7ndb_2 diff --git a/mysql-test/collections/test-bt b/mysql-test/collections/test-bt index 3127e2aecb9..58f0c2c3cde 100644 --- a/mysql-test/collections/test-bt +++ b/mysql-test/collections/test-bt @@ -1,10 +1,10 @@ -perl mysql-test-run.pl --force --timer --comment=normal --skip-ndbcluster --report-features --experimental=collections/default.experimental -perl mysql-test-run.pl --force --timer --comment=ps --skip-ndbcluster --ps-protocol --experimental=collections/default.experimental -perl mysql-test-run.pl --force --timer --comment=funcs1+ps --suite=funcs_1 --ps-protocol --experimental=collections/default.experimental -perl mysql-test-run.pl --force --timer --comment=funcs2 --suite=funcs_2 --experimental=collections/default.experimental -perl mysql-test-run.pl --force --timer --comment=partitions --suite=parts --experimental=collections/default.experimental -perl mysql-test-run.pl --force --timer --comment=stress --suite=stress --experimental=collections/default.experimental -perl mysql-test-run.pl --force --timer --comment=jp --suite=jp --experimental=collections/default.experimental -perl mysql-test-run.pl --force --timer --comment=embedded --embedded-server --skip-rpl --skip-ndbcluster --experimental=collections/default.experimental -perl mysql-test-run.pl --force --timer --comment=nist --suite=nist --experimental=collections/default.experimental -perl mysql-test-run.pl --force --timer --comment=nist+ps --suite=nist --ps-protocol --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=normal --skip-ndbcluster --report-features --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=ps --skip-ndbcluster --ps-protocol --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=funcs1+ps --suite=funcs_1 --ps-protocol --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=funcs2 --suite=funcs_2 --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=partitions --suite=parts --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=stress --suite=stress --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=jp --suite=jp --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=embedded --embedded-server --skip-rpl --skip-ndbcluster --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=nist --suite=nist --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=nist+ps --suite=nist --ps-protocol --experimental=collections/default.experimental diff --git a/mysql-test/collections/test-bt-debug b/mysql-test/collections/test-bt-debug index aec3d9fbef5..5fc1e15e0d2 100644 --- a/mysql-test/collections/test-bt-debug +++ b/mysql-test/collections/test-bt-debug @@ -1 +1 @@ -perl mysql-test-run.pl --force --timer --comment=debug --skip-ndbcluster --skip-rpl --report-features --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=debug --skip-ndbcluster --skip-rpl --report-features --experimental=collections/default.experimental diff --git a/mysql-test/collections/test-bt-fast b/mysql-test/collections/test-bt-fast index c3ded443518..7978c8082f0 100644 --- a/mysql-test/collections/test-bt-fast +++ b/mysql-test/collections/test-bt-fast @@ -1,2 +1,2 @@ -perl mysql-test-run.pl --force --timer --comment=ps --skip-ndbcluster --ps-protocol --report-features --experimental=collections/default.experimental -perl mysql-test-run.pl --force --timer --comment=stress --suite=stress --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=ps --skip-ndbcluster --ps-protocol --report-features --experimental=collections/default.experimental +perl mysql-test-run.pl --force --timer --parallel=auto --comment=stress --suite=stress --experimental=collections/default.experimental From 8282ddc430661b62f481b7134cfafd5cb77b97de Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 3 Dec 2010 17:17:45 +0000 Subject: [PATCH 060/110] BUG#46697: Table name in error message is not populated When a query fails with a different error on the slave, the sql thread outputs a message (M) containing: 1. the error message format for the master error code 2. the master error code 3. the error message for the slave's error code 4. the slave error code Given that the slave has no information on the error message itself that the master outputs, it can only print its own version of the message format (but stripped from the additional data if the message format requires). This may confuse users. To fix this we augment the slave's message (M) to explicitly state that the master's message is actually an error message format, the one associated with the given master error code and that the slave server knows about. --- mysql-test/suite/rpl/r/rpl_stm_EE_err2.result | 2 +- sql/log_event.cc | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_stm_EE_err2.result b/mysql-test/suite/rpl/r/rpl_stm_EE_err2.result index e69952787fb..da24c4f5db1 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_EE_err2.result +++ b/mysql-test/suite/rpl/r/rpl_stm_EE_err2.result @@ -11,6 +11,6 @@ set sql_log_bin=1; insert into t1 values(1),(2); ERROR 23000: Duplicate entry '2' for key 'a' drop table t1; -Error: "Query caused different errors on master and slave. Error on master: 'Duplicate entry '%-.192s' for key %d' (1062), Error on slave: 'no error' (0). Default database: 'test'. Query: 'insert into t1 values(1),(2)'" (expected different error codes on master and slave) +Error: "Query caused different errors on master and slave. Error on master: message format='Duplicate entry '%-.192s' for key %d' error code=1062 ; Error on slave: actual message='no error', error code=0. Default database: 'test'. Query: 'insert into t1 values(1),(2)'" (expected different error codes on master and slave) Errno: "0" (expected 0) drop table t1; diff --git a/sql/log_event.cc b/sql/log_event.cc index d0635ddac1a..b4599b8fd8c 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3337,7 +3337,8 @@ compare_errors: rli->report(ERROR_LEVEL, 0, "\ Query caused different errors on master and slave. \ -Error on master: '%s' (%d), Error on slave: '%s' (%d). \ +Error on master: message format='%s' error code=%d ; \ +Error on slave: actual message='%s', error code=%d. \ Default database: '%s'. Query: '%s'", ER_SAFE(expected_error), expected_error, From 93efc7e2c4bc8cffa235f2406db3bdaf4180189d Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 3 Dec 2010 20:49:08 +0300 Subject: [PATCH 061/110] Fix for bug #58669: read_only not enforced on 5.5.x Problem: "read-only" option ignored if it's enabled in the command line (or in the config file). Fix: sync opt_readonly (which is used for checks) with read_only (global var) when all server options are handled. --- mysql-test/r/bug58669.result | 17 +++++++++++++++++ mysql-test/t/bug58669-master.opt | 1 + mysql-test/t/bug58669.test | 22 ++++++++++++++++++++++ sql/mysqld.cc | 5 ++++- sql/mysqld.h | 3 ++- sql/sys_vars.cc | 11 ++++++++++- 6 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 mysql-test/r/bug58669.result create mode 100644 mysql-test/t/bug58669-master.opt create mode 100644 mysql-test/t/bug58669.test diff --git a/mysql-test/r/bug58669.result b/mysql-test/r/bug58669.result new file mode 100644 index 00000000000..5504c5908be --- /dev/null +++ b/mysql-test/r/bug58669.result @@ -0,0 +1,17 @@ +# +# Bug#58669: read_only not enforced on 5.5.x +# +CREATE USER user1@localhost; +CREATE DATABASE db1; +GRANT ALL PRIVILEGES ON db1.* TO user1@localhost; +CREATE TABLE db1.t1(a INT); +SELECT CURRENT_USER(); +CURRENT_USER() +user1@localhost +SHOW VARIABLES LIKE "%read_only%"; +Variable_name Value +read_only ON +INSERT INTO db1.t1 VALUES (1); +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +DROP DATABASE db1; +DROP USER user1@localhost; diff --git a/mysql-test/t/bug58669-master.opt b/mysql-test/t/bug58669-master.opt new file mode 100644 index 00000000000..6d909680527 --- /dev/null +++ b/mysql-test/t/bug58669-master.opt @@ -0,0 +1 @@ +--read-only diff --git a/mysql-test/t/bug58669.test b/mysql-test/t/bug58669.test new file mode 100644 index 00000000000..332c104cfea --- /dev/null +++ b/mysql-test/t/bug58669.test @@ -0,0 +1,22 @@ +--source include/not_embedded.inc + +--echo # +--echo # Bug#58669: read_only not enforced on 5.5.x +--echo # + +CREATE USER user1@localhost; +CREATE DATABASE db1; +GRANT ALL PRIVILEGES ON db1.* TO user1@localhost; +CREATE TABLE db1.t1(a INT); + +connect (con1,localhost,user1,,); +connection con1; +SELECT CURRENT_USER(); +SHOW VARIABLES LIKE "%read_only%"; +--error ER_OPTION_PREVENTS_STATEMENT +INSERT INTO db1.t1 VALUES (1); + +connection default; +disconnect con1; +DROP DATABASE db1; +DROP USER user1@localhost; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7fec30520d0..09c17d600a8 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -410,7 +410,8 @@ handlerton *heap_hton; handlerton *myisam_hton; handlerton *partition_hton; -my_bool opt_readonly= 0, use_temp_pool, relay_log_purge; +my_bool read_only= 0, opt_readonly= 0; +my_bool use_temp_pool, relay_log_purge; my_bool relay_log_recovery; my_bool opt_sync_frm, opt_allow_suspicious_udfs; my_bool opt_secure_auth= 0; @@ -7342,6 +7343,8 @@ static int get_options(int *argc_ptr, char ***argv_ptr) test(global_system_variables.optimizer_switch & OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN); + opt_readonly= read_only; + return 0; } diff --git a/sql/mysqld.h b/sql/mysqld.h index 376d8440619..7fe4dc7258a 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -107,7 +107,8 @@ extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; extern my_bool opt_slave_compressed_protocol, use_temp_pool; extern ulong slave_exec_mode_options; extern ulonglong slave_type_conversions_options; -extern my_bool opt_readonly, lower_case_file_system; +extern my_bool read_only, opt_readonly; +extern my_bool lower_case_file_system; extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; extern my_bool opt_secure_auth; extern char* opt_secure_file_priv; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 5c9df82ddac..9ca97b5dded 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1436,7 +1436,6 @@ static Sys_var_ulong Sys_read_buff_size( VALID_RANGE(IO_SIZE*2, INT_MAX32), DEFAULT(128*1024), BLOCK_SIZE(IO_SIZE)); -static my_bool read_only; static bool check_read_only(sys_var *self, THD *thd, set_var *var) { /* Prevent self dead-lock */ @@ -1520,6 +1519,16 @@ static bool fix_read_only(sys_var *self, THD *thd, enum_var_type type) read_only= opt_readonly; DBUG_RETURN(result); } + + +/** + The read_only boolean is always equal to the opt_readonly boolean except + during fix_read_only(); when that function is entered, opt_readonly is + the pre-update value and read_only is the post-update value. + fix_read_only() compares them and runs needed operations for the + transition (especially when transitioning from false to true) and + synchronizes both booleans in the end. +*/ static Sys_var_mybool Sys_readonly( "read_only", "Make all non-temporary tables read-only, with the exception for " From 4406a7de4d5df4de64f4fb63f616d9852f13e7c8 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Mon, 6 Dec 2010 11:55:36 +0000 Subject: [PATCH 062/110] Post-push fix for BUG#57275. --- mysql-test/r/mysqld--help-win.result | 20 +++++++++++++------ .../r/binlog_stmt_cache_size_basic_64.result | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/mysqld--help-win.result b/mysql-test/r/mysqld--help-win.result index c5d7bb458c3..dfb53937245 100644 --- a/mysql-test/r/mysqld--help-win.result +++ b/mysql-test/r/mysqld--help-win.result @@ -32,10 +32,10 @@ The following options may be given as the first argument: file (Solves most 'table full' errors) --bind-address=name IP address to bind to. --binlog-cache-size=# - The size of the cache to hold the SQL statements for the - binary log during a transaction. If you often use big, - multi-statement transactions you can increase this to get - more performance + The size of the transactional cache for updates to + transactional engines for the binary log. If you often + use transactions containing many statements, you can + increase this to get more performance --binlog-direct-non-transactional-updates Causes updates to non-transactional engines using statement format to be written directly to binary log. @@ -66,6 +66,11 @@ The following options may be given as the first argument: The maximum size of a row-based binary log event in bytes. Rows will be grouped into events smaller than this size if possible. The value has to be a multiple of 256. + --binlog-stmt-cache-size=# + The size of the statement cache for updates to + non-transactional engines for the binary log. If you + often use statements updating a great number of rows, you + can increase this to get more performance --bootstrap Used by mysql installation scripts. --bulk-insert-buffer-size=# Size of tree cache used in bulk insert optimisation. Note @@ -277,14 +282,15 @@ The following options may be given as the first argument: --max-allowed-packet=# Max packet length to send to or receive from the server --max-binlog-cache-size=# - Can be used to restrict the total size used to cache a - multi-transaction query + Sets the total size of the transactional cache --max-binlog-dump-events=# Option used by mysql-test for debugging and testing of replication. --max-binlog-size=# Binary log will be rotated automatically when the size exceeds this value. Will also apply to relay logs if max_relay_log_size is 0 + --max-binlog-stmt-cache-size=# + Sets the total size of the statement cache --max-connect-errors=# If there is more than this number of interrupted connections from a host this host will be blocked from @@ -738,6 +744,7 @@ binlog-cache-size 32768 binlog-direct-non-transactional-updates FALSE binlog-format STATEMENT binlog-row-event-max-size 1024 +binlog-stmt-cache-size 32768 bulk-insert-buffer-size 8388608 character-set-client-handshake TRUE character-set-filesystem binary @@ -816,6 +823,7 @@ max-allowed-packet 1048576 max-binlog-cache-size 18446744073709547520 max-binlog-dump-events 0 max-binlog-size 1073741824 +max-binlog-stmt-cache-size 18446744073709547520 max-connect-errors 10 max-connections 151 max-delayed-threads 20 diff --git a/mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_64.result b/mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_64.result index 604f671d5a4..7cb553e48ee 100644 --- a/mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_64.result +++ b/mysql-test/suite/sys_vars/r/binlog_stmt_cache_size_basic_64.result @@ -59,7 +59,7 @@ Warnings: Warning 1292 Truncated incorrect binlog_stmt_cache_size value: '42949672950' SELECT @@global.binlog_stmt_cache_size; @@global.binlog_stmt_cache_size -4294963200 +42949668864 'Bug: Errors are not coming on assigning invalid values to variable' SET @@global.binlog_stmt_cache_size = ON; ERROR 42000: Incorrect argument type to variable 'binlog_stmt_cache_size' From 5791d69d14aea7c76a62203e7467ecaf499e2003 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 7 Dec 2010 11:40:38 +0000 Subject: [PATCH 063/110] bug#58766: Server binary was compiled without fast-mutexes Re-enable fast mutexes on Linux for release builds. --- cmake/build_configurations/mysql_release.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index 56a6d897318..1838b0bb669 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -117,8 +117,8 @@ IF(UNIX) OPTION(WITH_PIC "" ON) # Why? - # Ensure aio is available on Linux (required by InnoDB) IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # Ensure aio is available on Linux (required by InnoDB) CHECK_INCLUDE_FILES(libaio.h HAVE_LIBAIO_H) CHECK_LIBRARY_EXISTS(aio io_queue_init "" HAVE_LIBAIO) IF(NOT HAVE_LIBAIO_H OR NOT HAVE_LIBAIO) @@ -130,6 +130,9 @@ IF(UNIX) SuSE: zypper install libaio-devel ") ENDIF() + + # Enable fast mutexes on Linux + OPTION(WITH_FAST_MUTEXES "" ON) ENDIF() ENDIF() From d5e7008bddb6a7192c46c0c8f9100e5b099e71b0 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Tue, 7 Dec 2010 17:37:07 +0530 Subject: [PATCH 064/110] Bug#58139 : default-auth option not recognized in MySQL standard command line clients. Command line tools like mysqladmin and mysqldump did not recognize default-auth and plugin-dir options. Support for these options was found missing in these command line tools. Fixed by adding support for the same. --- client/mysqladmin.cc | 14 ++++++++++++++ client/mysqldump.c | 15 +++++++++++++++ mysql-test/r/plugin_auth.result | 10 ++++++++++ mysql-test/t/plugin_auth.test | 14 ++++++++++++++ 4 files changed, 53 insertions(+) diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 342a67fbc29..4c4747c25de 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -44,6 +44,7 @@ static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations; static uint opt_count_iterations= 0, my_end_arg; static ulong opt_connect_timeout, opt_shutdown_timeout; static char * unix_port=0; +static char *opt_plugin_dir= 0, *opt_default_auth; #ifdef HAVE_SMEM static char *shared_memory_base_name=0; @@ -206,6 +207,13 @@ static struct my_option my_long_options[] = {"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", &opt_shutdown_timeout, &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG, SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0}, + {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"default_auth", OPT_PLUGIN_DIR, + "Default authentication client-side plugin to use.", + (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -342,6 +350,12 @@ int main(int argc,char *argv[]) mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); error_flags= (myf)(opt_nobeep ? 0 : ME_BELL); + if (opt_plugin_dir && *opt_plugin_dir) + mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir); + + if (opt_default_auth && *opt_default_auth) + mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth); + if (sql_connect(&mysql, option_wait)) { /* diff --git a/client/mysqldump.c b/client/mysqldump.c index b47d88290a5..2d38e94f0fb 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -137,6 +137,7 @@ FILE *stderror_file=0; static char *shared_memory_base_name=0; #endif static uint opt_protocol= 0; +static char *opt_plugin_dir= 0, *opt_default_auth; /* Dynamic_string wrapper functions. In this file use these @@ -499,6 +500,13 @@ static struct my_option my_long_options[] = &where, &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"default_auth", OPT_PLUGIN_DIR, + "Default authentication client-side plugin to use.", + (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1452,6 +1460,13 @@ static int connect_to_db(char *host, char *user,char *passwd) mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); #endif mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset); + + if (opt_plugin_dir && *opt_plugin_dir) + mysql_options(&mysql_connection, MYSQL_PLUGIN_DIR, opt_plugin_dir); + + if (opt_default_auth && *opt_default_auth) + mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth); + if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd, NULL,opt_mysql_port,opt_mysql_unix_port, 0))) diff --git a/mysql-test/r/plugin_auth.result b/mysql-test/r/plugin_auth.result index 8a649f63598..b155b296ac1 100644 --- a/mysql-test/r/plugin_auth.result +++ b/mysql-test/r/plugin_auth.result @@ -318,4 +318,14 @@ Proxied_host Proxied_user With_grant 1 FLUSH PRIVILEGES; +# +# Bug#58139 : default-auth option not recognized in MySQL standardi +# command line clients +# +# Executing 'mysql' +1 +1 +# Executing 'mysqladmin' +mysqld is alive +# Executing 'mysqldump' End of 5.5 tests diff --git a/mysql-test/t/plugin_auth.test b/mysql-test/t/plugin_auth.test index 3b1dd93c4d1..351f61c57d1 100644 --- a/mysql-test/t/plugin_auth.test +++ b/mysql-test/t/plugin_auth.test @@ -394,4 +394,18 @@ FLUSH PRIVILEGES; FLUSH PRIVILEGES; +--echo # +--echo # Bug#58139 : default-auth option not recognized in MySQL standardi +--echo # command line clients +--echo # + +--echo # Executing 'mysql' +--exec $MYSQL -u root -S $MASTER_MYSOCK -P $MASTER_MYPORT --default-auth=auth_test_plugin $PLUGIN_AUTH_OPT -e 'SELECT 1' + +--echo # Executing 'mysqladmin' +--exec $MYSQLADMIN -u root -S $MASTER_MYSOCK -P $MASTER_MYPORT --default-auth=auth_test_plugin $PLUGIN_AUTH_OPT ping + +--echo # Executing 'mysqldump' +--exec $MYSQL_DUMP -u root -S $MASTER_MYSOCK -P $MASTER_MYPORT --compact --default-auth=auth_test_plugin $PLUGIN_AUTH_OPT test + --echo End of 5.5 tests From 83b7c749886abe28d8ff8e26b45940d16488f7df Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Tue, 7 Dec 2010 14:52:14 +0100 Subject: [PATCH 065/110] Valgrind 3.5.0 cleanup --- mysql-test/valgrind.supp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 0d63c2cb3ff..ab79a01385c 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -770,13 +770,15 @@ fun:lf_hash_insert } +# +# Note that initialize_bucket() is reccursive, +# can't provide more stack context. +# { missing shutdown_performance_schema 3 Memcheck:Leak fun:malloc fun:my_malloc fun:initialize_bucket - fun:lf_hash_search - fun:_Z19find_or_create_fileP10PFS_threadP14PFS_file_classPKcj } From 848e1b90cd4bdf4c262364d3a2613d9f7499b1bc Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Tue, 7 Dec 2010 15:13:27 +0100 Subject: [PATCH 066/110] Valgrind 3.5.0 cleanup, continued --- mysql-test/valgrind.supp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index ab79a01385c..bb3a95208bb 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -782,3 +782,40 @@ fun:initialize_bucket } +{ + missing shutdown_performance_schema 4 + Memcheck:Leak + fun:malloc + fun:my_malloc + fun:_lf_dynarray_lvalue + fun:_lf_pinbox_get_pins + fun:lf_pinbox_get_pins +} + +{ + missing shutdown_performance_schema 5 + Memcheck:Leak + fun:malloc + fun:my_malloc + fun:_lf_dynarray_lvalue + fun:lf_hash_insert +} + +{ + missing shutdown_performance_schema 6 + Memcheck:Leak + fun:malloc + fun:my_malloc + fun:_lf_dynarray_lvalue + fun:lf_hash_delete +} + +{ + missing shutdown_performance_schema 7 + Memcheck:Leak + fun:malloc + fun:my_malloc + fun:_lf_dynarray_lvalue + fun:lf_hash_search +} + From 6a84582c671e9ddcb35016a29c576f73b00b562e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 7 Dec 2010 13:06:20 -0200 Subject: [PATCH 067/110] Bug#57991: Compiler flag change build error : adler32.c Do not use the same maintainer mode flags for both GCC and ICC. The -Wall option for ICC enables more warnings than its GCC counterpart. --- config/ac-macros/maintainer.m4 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config/ac-macros/maintainer.m4 b/config/ac-macros/maintainer.m4 index b4d2f08e558..5b6ec591e60 100644 --- a/config/ac-macros/maintainer.m4 +++ b/config/ac-macros/maintainer.m4 @@ -15,8 +15,11 @@ AC_DEFUN([MY_MAINTAINER_MODE], [ # Set warning options required under maintainer mode. AC_DEFUN([MY_MAINTAINER_MODE_WARNINGS], [ + # Detect ICC posing as GCC. + AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER], + [INTEL_COMPILER=no], [INTEL_COMPILER=yes]) # Setup GCC warning options. - AS_IF([test "$GCC" = "yes"], [ + AS_IF([test "$GCC" = "yes" -a "$INTEL_COMPILER" = "no"], [ 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" From 447c50307367c64188f000ae4ab95858f5c9d891 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Tue, 7 Dec 2010 21:14:07 +0530 Subject: [PATCH 068/110] Additional fix in the test for Bug#58139. --- mysql-test/t/plugin_auth.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/plugin_auth.test b/mysql-test/t/plugin_auth.test index 351f61c57d1..49fbfa6995b 100644 --- a/mysql-test/t/plugin_auth.test +++ b/mysql-test/t/plugin_auth.test @@ -400,7 +400,7 @@ FLUSH PRIVILEGES; --echo # --echo # Executing 'mysql' ---exec $MYSQL -u root -S $MASTER_MYSOCK -P $MASTER_MYPORT --default-auth=auth_test_plugin $PLUGIN_AUTH_OPT -e 'SELECT 1' +--exec $MYSQL -u root -S $MASTER_MYSOCK -P $MASTER_MYPORT --default-auth=auth_test_plugin $PLUGIN_AUTH_OPT -e "SELECT 1" --echo # Executing 'mysqladmin' --exec $MYSQLADMIN -u root -S $MASTER_MYSOCK -P $MASTER_MYPORT --default-auth=auth_test_plugin $PLUGIN_AUTH_OPT ping From bd0709cc8726e2d189df71138488ff7b2b004460 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 7 Dec 2010 15:48:18 +0000 Subject: [PATCH 069/110] BUG#46166 Post merge fix. In write_incident, check if binlog file is opened before actually trying to write the incident event. --- sql/log.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sql/log.cc b/sql/log.cc index 46dcec2e2cd..5fcb5fe0367 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4828,6 +4828,10 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock) { uint error= 0; DBUG_ENTER("MYSQL_BIN_LOG::write_incident"); + + if (!is_open()) + DBUG_RETURN(error); + LEX_STRING const write_error_msg= { C_STRING_WITH_LEN("error writing to the binary log") }; Incident incident= INCIDENT_LOST_EVENTS; From 957c09f66329c25092aaf271a284ce64081c401f Mon Sep 17 00:00:00 2001 From: Guilhem Bichot Date: Tue, 7 Dec 2010 16:59:32 +0100 Subject: [PATCH 070/110] Fix for Bug#57932 "query with avg returns incorrect results": when there was one NULL value, AVG(DISTINCT) could forget about other values. See commit comment of item_sum.cc. --- mysql-test/r/func_group.result | 15 ++++++ mysql-test/t/func_group.test | 11 +++++ sql/item_sum.cc | 84 ++++++++++++++++++---------------- sql/item_sum.h | 16 +++++++ 4 files changed, 87 insertions(+), 39 deletions(-) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 5f874f4665d..bc295ec7b44 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1746,3 +1746,18 @@ MAX(c1) MIN(c1) -00:00:01 -00:00:01 DROP TABLE t1; # End of the bug#56120 +# +# Bug#57932 "query with AVG(DISTINCT) returns NULL if last +# aggregated value was NULL" +# +CREATE TABLE t1 (col_int_nokey int(11)); +INSERT INTO t1 VALUES (7),(8),(NULL); +SELECT AVG(DISTINCT col_int_nokey) FROM t1; +AVG(DISTINCT col_int_nokey) +7.5000 +SELECT AVG(DISTINCT outr.col_int_nokey) FROM t1 AS outr LEFT JOIN t1 AS outr2 ON +outr.col_int_nokey = outr2.col_int_nokey; +AVG(DISTINCT outr.col_int_nokey) +7.5000 +DROP TABLE t1; +# End of the bug#57932 diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 6d128be7f34..9a9c5442d87 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1118,3 +1118,14 @@ SELECT MAX(c1),MIN(c1) FROM t1; DROP TABLE t1; --echo # End of the bug#56120 +--echo # +--echo # Bug#57932 "query with AVG(DISTINCT) returns NULL if last +--echo # aggregated value was NULL" +--echo # +CREATE TABLE t1 (col_int_nokey int(11)); +INSERT INTO t1 VALUES (7),(8),(NULL); +SELECT AVG(DISTINCT col_int_nokey) FROM t1; +SELECT AVG(DISTINCT outr.col_int_nokey) FROM t1 AS outr LEFT JOIN t1 AS outr2 ON +outr.col_int_nokey = outr2.col_int_nokey; +DROP TABLE t1; +--echo # End of the bug#57932 diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 8cd8e1bb222..cf95fc3969f 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1325,27 +1325,11 @@ void Item_sum_sum::fix_length_and_dec() bool Item_sum_sum::add() { DBUG_ENTER("Item_sum_sum::add"); - bool arg_is_null; if (hybrid_type == DECIMAL_RESULT) { - my_decimal value, *val; - if (aggr->use_distinct_values) - { - /* - We are aggregating distinct rows. Get the value from the distinct - table pointer - */ - Aggregator_distinct *daggr= (Aggregator_distinct *)aggr; - val= daggr->table->field[0]->val_decimal (&value); - arg_is_null= daggr->table->field[0]->is_null(); - } - else - { - /* non-distinct aggregation */ - val= args[0]->val_decimal(&value); - arg_is_null= args[0]->null_value; - } - if (!arg_is_null) + my_decimal value; + const my_decimal *val= aggr->arg_val_decimal(&value); + if (!aggr->arg_is_null()) { my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1), val, dec_buffs + curr_dec_buff); @@ -1355,25 +1339,8 @@ bool Item_sum_sum::add() } else { - double val; - if (aggr->use_distinct_values) - { - /* - We are aggregating distinct rows. Get the value from the distinct - table pointer - */ - Aggregator_distinct *daggr= (Aggregator_distinct *)aggr; - val= daggr->table->field[0]->val_real (); - arg_is_null= daggr->table->field[0]->is_null(); - } - else - { - /* non-distinct aggregation */ - val= args[0]->val_real(); - arg_is_null= args[0]->null_value; - } - sum+= val; - if (!arg_is_null) + sum+= aggr->arg_val_real(); + if (!aggr->arg_is_null()) null_value= 0; } DBUG_RETURN(0); @@ -1471,6 +1438,45 @@ Aggregator_distinct::~Aggregator_distinct() } +my_decimal *Aggregator_simple::arg_val_decimal(my_decimal *value) +{ + return item_sum->args[0]->val_decimal(value); +} + + +double Aggregator_simple::arg_val_real() +{ + return item_sum->args[0]->val_real(); +} + + +bool Aggregator_simple::arg_is_null() +{ + return item_sum->args[0]->null_value; +} + + +my_decimal *Aggregator_distinct::arg_val_decimal(my_decimal * value) +{ + return use_distinct_values ? table->field[0]->val_decimal(value) : + item_sum->args[0]->val_decimal(value); +} + + +double Aggregator_distinct::arg_val_real() +{ + return use_distinct_values ? table->field[0]->val_real() : + item_sum->args[0]->val_real(); +} + + +bool Aggregator_distinct::arg_is_null() +{ + return use_distinct_values ? table->field[0]->is_null() : + item_sum->args[0]->null_value; +} + + Item *Item_sum_count::copy_or_same(THD* thd) { return new (thd->mem_root) Item_sum_count(thd, this); @@ -1576,7 +1582,7 @@ bool Item_sum_avg::add() { if (Item_sum_sum::add()) return TRUE; - if (!args[0]->null_value) + if (!aggr->arg_is_null()) count++; return FALSE; } diff --git a/sql/item_sum.h b/sql/item_sum.h index 06a8c2c58a4..c7159568c40 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -101,6 +101,15 @@ public: */ virtual void endup() = 0; + /** Decimal value of being-aggregated argument */ + virtual my_decimal *arg_val_decimal(my_decimal * value) = 0; + /** Floating point value of being-aggregated argument */ + virtual double arg_val_real() = 0; + /** + NULLness of being-aggregated argument; can be called only after + arg_val_decimal() or arg_val_real(). + */ + virtual bool arg_is_null() = 0; }; @@ -304,6 +313,7 @@ class st_select_lex; class Item_sum :public Item_result_field { friend class Aggregator_distinct; + friend class Aggregator_simple; protected: /** @@ -600,6 +610,9 @@ public: void clear(); bool add(); void endup(); + virtual my_decimal *arg_val_decimal(my_decimal * value); + virtual double arg_val_real(); + virtual bool arg_is_null(); bool unique_walk_function(void *element); static int composite_key_cmp(void* arg, uchar* key1, uchar* key2); @@ -623,6 +636,9 @@ public: void clear() { item_sum->clear(); } bool add() { return item_sum->add(); } void endup() {}; + virtual my_decimal *arg_val_decimal(my_decimal * value); + virtual double arg_val_real(); + virtual bool arg_is_null(); }; From 1b94ba5407d125b03550ce7231714fab8c634cc9 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 7 Dec 2010 16:55:25 +0000 Subject: [PATCH 071/110] BUG#46166 Post merge fixes for mysql-5.5-bugteam. --- mysql-test/suite/binlog/r/binlog_max_extension.result | 3 +-- mysql-test/suite/binlog/t/binlog_max_extension.test | 3 ++- sql/log.cc | 2 +- sql/slave.cc | 3 ++- sql/sql_repl.cc | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_max_extension.result b/mysql-test/suite/binlog/r/binlog_max_extension.result index af341db4536..f69ffcce16a 100644 --- a/mysql-test/suite/binlog/r/binlog_max_extension.result +++ b/mysql-test/suite/binlog/r/binlog_max_extension.result @@ -3,6 +3,5 @@ call mtr.add_suppression("Log filename extension number exhausted:"); call mtr.add_suppression("Can't generate a unique log-filename"); RESET MASTER; FLUSH LOGS; -Warnings: -Warning 1098 Can't generate a unique log-filename master-bin.(1-999) +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) diff --git a/mysql-test/suite/binlog/t/binlog_max_extension.test b/mysql-test/suite/binlog/t/binlog_max_extension.test index 4525ce41aed..e5274d87b85 100644 --- a/mysql-test/suite/binlog/t/binlog_max_extension.test +++ b/mysql-test/suite/binlog/t/binlog_max_extension.test @@ -58,7 +58,8 @@ EOF # Assertion ########### -# assertion: should throw warning +# assertion: should raise error +-- error ER_NO_UNIQUE_LOGFILE FLUSH LOGS; ############## diff --git a/sql/log.cc b/sql/log.cc index 234fbae6961..b20feb31d5f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -5111,7 +5111,7 @@ int MYSQL_BIN_LOG::rotate_and_purge(uint flags) to the current log. */ if (!write_incident(current_thd, FALSE)) - flush_and_sync(); + flush_and_sync(0); #ifdef HAVE_REPLICATION check_purge= true; diff --git a/sql/slave.cc b/sql/slave.cc index 8568a119fe8..e081d2406be 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -523,7 +523,8 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock) if (flush_master_info(mi, TRUE, FALSE)) DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS); - if (my_sync(mi->rli.relay_log.get_log_file()->file, MYF(MY_WME))) + if (mi->rli.relay_log.is_open() && + my_sync(mi->rli.relay_log.get_log_file()->file, MYF(MY_WME))) DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS); if (my_sync(mi->fd, MYF(MY_WME))) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 7bca41f1265..4e8b70c58f6 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1925,7 +1925,7 @@ bool show_binlogs(THD* thd) if (!mysql_bin_log.is_open()) { - my_message(ER_NO_BINARY_LOGGING, ER(ER_NO_BINARY_LOGGING), MYF(0)); + my_error(ER_NO_BINARY_LOGGING, MYF(0)); DBUG_RETURN(TRUE); } From d33574fbf747aac57fc9f16b669ee92ad66d06f6 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Tue, 7 Dec 2010 20:08:54 +0300 Subject: [PATCH 072/110] Fix for bug #58669: read_only not enforced on 5.5.x merged from mysql-5.5.8-release tree, revision: ramil@mysql.com-20101203174908-217tdkn150vieha9 --- mysql-test/r/bug58669.result | 17 +++++++++++++++++ mysql-test/t/bug58669-master.opt | 1 + mysql-test/t/bug58669.test | 22 ++++++++++++++++++++++ sql/mysqld.cc | 5 ++++- sql/mysqld.h | 3 ++- sql/sys_vars.cc | 11 ++++++++++- 6 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 mysql-test/r/bug58669.result create mode 100644 mysql-test/t/bug58669-master.opt create mode 100644 mysql-test/t/bug58669.test diff --git a/mysql-test/r/bug58669.result b/mysql-test/r/bug58669.result new file mode 100644 index 00000000000..5504c5908be --- /dev/null +++ b/mysql-test/r/bug58669.result @@ -0,0 +1,17 @@ +# +# Bug#58669: read_only not enforced on 5.5.x +# +CREATE USER user1@localhost; +CREATE DATABASE db1; +GRANT ALL PRIVILEGES ON db1.* TO user1@localhost; +CREATE TABLE db1.t1(a INT); +SELECT CURRENT_USER(); +CURRENT_USER() +user1@localhost +SHOW VARIABLES LIKE "%read_only%"; +Variable_name Value +read_only ON +INSERT INTO db1.t1 VALUES (1); +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +DROP DATABASE db1; +DROP USER user1@localhost; diff --git a/mysql-test/t/bug58669-master.opt b/mysql-test/t/bug58669-master.opt new file mode 100644 index 00000000000..6d909680527 --- /dev/null +++ b/mysql-test/t/bug58669-master.opt @@ -0,0 +1 @@ +--read-only diff --git a/mysql-test/t/bug58669.test b/mysql-test/t/bug58669.test new file mode 100644 index 00000000000..332c104cfea --- /dev/null +++ b/mysql-test/t/bug58669.test @@ -0,0 +1,22 @@ +--source include/not_embedded.inc + +--echo # +--echo # Bug#58669: read_only not enforced on 5.5.x +--echo # + +CREATE USER user1@localhost; +CREATE DATABASE db1; +GRANT ALL PRIVILEGES ON db1.* TO user1@localhost; +CREATE TABLE db1.t1(a INT); + +connect (con1,localhost,user1,,); +connection con1; +SELECT CURRENT_USER(); +SHOW VARIABLES LIKE "%read_only%"; +--error ER_OPTION_PREVENTS_STATEMENT +INSERT INTO db1.t1 VALUES (1); + +connection default; +disconnect con1; +DROP DATABASE db1; +DROP USER user1@localhost; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 840962b2432..49523a5b007 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -410,7 +410,8 @@ handlerton *heap_hton; handlerton *myisam_hton; handlerton *partition_hton; -my_bool opt_readonly= 0, use_temp_pool, relay_log_purge; +my_bool read_only= 0, opt_readonly= 0; +my_bool use_temp_pool, relay_log_purge; my_bool relay_log_recovery; my_bool opt_sync_frm, opt_allow_suspicious_udfs; my_bool opt_secure_auth= 0; @@ -7349,6 +7350,8 @@ static int get_options(int *argc_ptr, char ***argv_ptr) test(global_system_variables.optimizer_switch & OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN); + opt_readonly= read_only; + return 0; } diff --git a/sql/mysqld.h b/sql/mysqld.h index 712b26382d1..5d8885ac277 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -107,7 +107,8 @@ extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; extern my_bool opt_slave_compressed_protocol, use_temp_pool; extern ulong slave_exec_mode_options; extern ulonglong slave_type_conversions_options; -extern my_bool opt_readonly, lower_case_file_system; +extern my_bool read_only, opt_readonly; +extern my_bool lower_case_file_system; extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; extern my_bool opt_secure_auth; extern char* opt_secure_file_priv; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index ed2c44fb03f..68bb77d467f 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1452,7 +1452,6 @@ static Sys_var_ulong Sys_read_buff_size( VALID_RANGE(IO_SIZE*2, INT_MAX32), DEFAULT(128*1024), BLOCK_SIZE(IO_SIZE)); -static my_bool read_only; static bool check_read_only(sys_var *self, THD *thd, set_var *var) { /* Prevent self dead-lock */ @@ -1536,6 +1535,16 @@ static bool fix_read_only(sys_var *self, THD *thd, enum_var_type type) read_only= opt_readonly; DBUG_RETURN(result); } + + +/** + The read_only boolean is always equal to the opt_readonly boolean except + during fix_read_only(); when that function is entered, opt_readonly is + the pre-update value and read_only is the post-update value. + fix_read_only() compares them and runs needed operations for the + transition (especially when transitioning from false to true) and + synchronizes both booleans in the end. +*/ static Sys_var_mybool Sys_readonly( "read_only", "Make all non-temporary tables read-only, with the exception for " From 537366fd24cd383c8c11cda060957ff604a65d6b Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Tue, 7 Dec 2010 21:00:33 +0100 Subject: [PATCH 073/110] Bug#58798 SHOW ENGINE PERFORMANCE_SCHEMA STATUS: incorrect table lettercase Before this fix, the output of SHOW ENGINE PERFORMANCE_SCHEMA STATUS used uppercase to name performance schema tables. This is inconsistent since performance schema tables have been renamed to lowercase. Also, an old table 'PROCESSLIST' was still visible, even after this table got renamed to 'threads'. This fix: - correctly uses lowercases in the output, to match the current naming. - replaced 'PROCESSLIST' with 'threads'. Tested the output of SHOW ENGINE PERFORMANCE_SCHEMA STATUS manually. No automated test cases can be written for this, since the output is too platform dependent (sizes). --- storage/perfschema/pfs_engine_table.cc | 106 ++++++++++++------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index cec068a686b..38f6df3003d 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -519,9 +519,9 @@ bool pfs_show_status(handlerton *hton, THD *thd, /* Note about naming conventions: - Internal buffers exposed as a table in the performance schema are named - after the table, as in 'EVENTS_WAITS_CURRENT' + after the table, as in 'events_waits_current' - Internal buffers not exposed by a table are named with parenthesis, - as in '(PFS_MUTEX_CLASS)'. + as in '(pfs_mutex_class)'. */ if (stat != HA_ENGINE_STATUS) DBUG_RETURN(false); @@ -532,219 +532,219 @@ bool pfs_show_status(handlerton *hton, THD *thd, { switch (i){ case 0: - name= "EVENTS_WAITS_CURRENT.ROW_SIZE"; + name= "events_waits_current.row_size"; size= sizeof(PFS_wait_locker); break; case 1: - name= "EVENTS_WAITS_CURRENT.ROW_COUNT"; + name= "events_waits_current.row_count"; size= LOCKER_STACK_SIZE * thread_max; break; case 2: - name= "EVENTS_WAITS_HISTORY.ROW_SIZE"; + name= "events_waits_history.row_size"; size= sizeof(PFS_events_waits); break; case 3: - name= "EVENTS_WAITS_HISTORY.ROW_COUNT"; + name= "events_waits_history.row_count"; size= events_waits_history_per_thread * thread_max; break; case 4: - name= "EVENTS_WAITS_HISTORY.MEMORY"; + name= "events_waits_history.memory"; size= events_waits_history_per_thread * thread_max * sizeof(PFS_events_waits); total_memory+= size; break; case 5: - name= "EVENTS_WAITS_HISTORY_LONG.ROW_SIZE"; + name= "events_waits_history_long.row_size"; size= sizeof(PFS_events_waits); break; case 6: - name= "EVENTS_WAITS_HISTORY_LONG.ROW_COUNT"; + name= "events_waits_history_long.row_count"; size= events_waits_history_long_size; break; case 7: - name= "EVENTS_WAITS_HISTORY_LONG.MEMORY"; + name= "events_waits_history_long.memory"; size= events_waits_history_long_size * sizeof(PFS_events_waits); total_memory+= size; break; case 8: - name= "(PFS_MUTEX_CLASS).ROW_SIZE"; + name= "(pfs_mutex_class).row_size"; size= sizeof(PFS_mutex_class); break; case 9: - name= "(PFS_MUTEX_CLASS).ROW_COUNT"; + name= "(pfs_mutex_class).row_count"; size= mutex_class_max; break; case 10: - name= "(PFS_MUTEX_CLASS).MEMORY"; + name= "(pfs_mutex_class).memory"; size= mutex_class_max * sizeof(PFS_mutex_class); total_memory+= size; break; case 11: - name= "(PFS_RWLOCK_CLASS).ROW_SIZE"; + name= "(pfs_rwlock_class).row_size"; size= sizeof(PFS_rwlock_class); break; case 12: - name= "(PFS_RWLOCK_CLASS).ROW_COUNT"; + name= "(pfs_rwlock_class).row_count"; size= rwlock_class_max; break; case 13: - name= "(PFS_RWLOCK_CLASS).MEMORY"; + name= "(pfs_rwlock_class).memory"; size= rwlock_class_max * sizeof(PFS_rwlock_class); total_memory+= size; break; case 14: - name= "(PFS_COND_CLASS).ROW_SIZE"; + name= "(pfs_cond_class).row_size"; size= sizeof(PFS_cond_class); break; case 15: - name= "(PFS_COND_CLASS).ROW_COUNT"; + name= "(pfs_cond_class).row_count"; size= cond_class_max; break; case 16: - name= "(PFS_COND_CLASS).MEMORY"; + name= "(pfs_cond_class).memory"; size= cond_class_max * sizeof(PFS_cond_class); total_memory+= size; break; case 17: - name= "(PFS_THREAD_CLASS).ROW_SIZE"; + name= "(pfs_thread_class).row_size"; size= sizeof(PFS_thread_class); break; case 18: - name= "(PFS_THREAD_CLASS).ROW_COUNT"; + name= "(pfs_thread_class).row_count"; size= thread_class_max; break; case 19: - name= "(PFS_THREAD_CLASS).MEMORY"; + name= "(pfs_thread_class).memory"; size= thread_class_max * sizeof(PFS_thread_class); total_memory+= size; break; case 20: - name= "(PFS_FILE_CLASS).ROW_SIZE"; + name= "(pfs_file_class).row_size"; size= sizeof(PFS_file_class); break; case 21: - name= "(PFS_FILE_CLASS).ROW_COUNT"; + name= "(pfs_file_class).row_count"; size= file_class_max; break; case 22: - name= "(PFS_FILE_CLASS).MEMORY"; + name= "(pfs_file_class).memory"; size= file_class_max * sizeof(PFS_file_class); total_memory+= size; break; case 23: - name= "MUTEX_INSTANCES.ROW_SIZE"; + name= "mutex_instances.row_size"; size= sizeof(PFS_mutex); break; case 24: - name= "MUTEX_INSTANCES.ROW_COUNT"; + name= "mutex_instances.row_count"; size= mutex_max; break; case 25: - name= "MUTEX_INSTANCES.MEMORY"; + name= "mutex_instances.memory"; size= mutex_max * sizeof(PFS_mutex); total_memory+= size; break; case 26: - name= "RWLOCK_INSTANCES.ROW_SIZE"; + name= "rwlock_instances.row_size"; size= sizeof(PFS_rwlock); break; case 27: - name= "RWLOCK_INSTANCES.ROW_COUNT"; + name= "rwlock_instances.row_count"; size= rwlock_max; break; case 28: - name= "RWLOCK_INSTANCES.MEMORY"; + name= "rwlock_instances.memory"; size= rwlock_max * sizeof(PFS_rwlock); total_memory+= size; break; case 29: - name= "COND_INSTANCES.ROW_SIZE"; + name= "cond_instances.row_size"; size= sizeof(PFS_cond); break; case 30: - name= "COND_INSTANCES.ROW_COUNT"; + name= "cond_instances.row_count"; size= cond_max; break; case 31: - name= "COND_INSTANCES.MEMORY"; + name= "cond_instances.memory"; size= cond_max * sizeof(PFS_cond); total_memory+= size; break; case 32: - name= "PROCESSLIST.ROW_SIZE"; + name= "threads.row_size"; size= sizeof(PFS_thread); break; case 33: - name= "PROCESSLIST.ROW_COUNT"; + name= "threads.row_count"; size= thread_max; break; case 34: - name= "PROCESSLIST.MEMORY"; + name= "threads.memory"; size= thread_max * sizeof(PFS_thread); total_memory+= size; break; case 35: - name= "FILE_INSTANCES.ROW_SIZE"; + name= "file_instances.row_size"; size= sizeof(PFS_file); break; case 36: - name= "FILE_INSTANCES.ROW_COUNT"; + name= "file_instances.row_count"; size= file_max; break; case 37: - name= "FILE_INSTANCES.MEMORY"; + name= "file_instances.memory"; size= file_max * sizeof(PFS_file); total_memory+= size; break; case 38: - name= "(PFS_FILE_HANDLE).ROW_SIZE"; + name= "(pfs_file_handle).row_size"; size= sizeof(PFS_file*); break; case 39: - name= "(PFS_FILE_HANDLE).ROW_COUNT"; + name= "(pfs_file_handle).row_count"; size= file_handle_max; break; case 40: - name= "(PFS_FILE_HANDLE).MEMORY"; + name= "(pfs_file_handle).memory"; size= file_handle_max * sizeof(PFS_file*); total_memory+= size; break; case 41: - name= "EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME.ROW_SIZE"; + name= "events_waits_summary_by_thread_by_event_name.row_size"; size= sizeof(PFS_single_stat_chain); break; case 42: - name= "EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME.ROW_COUNT"; + name= "events_waits_summary_by_thread_by_event_name.row_count"; size= thread_max * instr_class_per_thread; break; case 43: - name= "EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME.MEMORY"; + name= "events_waits_summary_by_thread_by_event_name.memory"; size= thread_max * instr_class_per_thread * sizeof(PFS_single_stat_chain); total_memory+= size; break; case 44: - name= "(PFS_TABLE_SHARE).ROW_SIZE"; + name= "(pfs_table_share).row_size"; size= sizeof(PFS_table_share); break; case 45: - name= "(PFS_TABLE_SHARE).ROW_COUNT"; + name= "(pfs_table_share).row_count"; size= table_share_max; break; case 46: - name= "(PFS_TABLE_SHARE).MEMORY"; + name= "(pfs_table_share).memory"; size= table_share_max * sizeof(PFS_table_share); total_memory+= size; break; case 47: - name= "(PFS_TABLE).ROW_SIZE"; + name= "(pfs_table).row_size"; size= sizeof(PFS_table); break; case 48: - name= "(PFS_TABLE).ROW_COUNT"; + name= "(pfs_table).row_count"; size= table_max; break; case 49: - name= "(PFS_TABLE).MEMORY"; + name= "(pfs_table).memory"; size= table_max * sizeof(PFS_table); total_memory+= size; break; @@ -753,7 +753,7 @@ bool pfs_show_status(handlerton *hton, THD *thd, for aggregation in total_memory. */ case 50: - name= "PERFORMANCE_SCHEMA.MEMORY"; + name= "performance_schema.memory"; size= total_memory; /* This will fail if something is not advertised here */ DBUG_ASSERT(size == pfs_allocated_memory); From 4e9fb2c76f65e9949ebd3bbe2608f6a3b80a3822 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 8 Dec 2010 14:28:06 +0200 Subject: [PATCH 074/110] Bug #57954: BIT_AND function returns incorrect results when semijoin=on When setting the aggregate function as having no rows to report the function no_rows_in_result() was calling Item_sum::reset(). However this function in addition to cleaning up the aggregate value by calling aggregator_clear() was also adding the current value to the aggregate value by calling aggregator_add(). Fixed by making no_rows_in_result() to call aggregator_clear() directly. Renamed Item_sum::reset to Item_sum::reset_and_add() to and added a comment to avoid misinterpretation of what the function does. --- mysql-test/r/func_group_innodb.result | 47 +++++++++++++++++++++++++ mysql-test/t/func_group_innodb.test | 50 +++++++++++++++++++++++++++ sql/item_sum.cc | 2 +- sql/item_sum.h | 20 +++++++---- sql/opt_range.cc | 4 +-- sql/opt_sum.cc | 2 +- sql/sql_select.cc | 2 +- 7 files changed, 116 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/func_group_innodb.result b/mysql-test/r/func_group_innodb.result index 908e85c1652..8412317c91d 100644 --- a/mysql-test/r/func_group_innodb.result +++ b/mysql-test/r/func_group_innodb.result @@ -145,3 +145,50 @@ select count(*), min(7), max(7) from t2m, t1i; count(*) min(7) max(7) 0 NULL NULL drop table t1m, t1i, t2m, t2i; +# +# Bug #57954: BIT_AND function returns incorrect results when +# semijoin=on +CREATE TABLE c ( +pk INT, +col_varchar_key VARCHAR(1), +PRIMARY KEY (pk), +KEY col_varchar_key (col_varchar_key) +) ENGINE=InnoDB; +INSERT INTO c VALUES (11,NULL); +INSERT INTO c VALUES (16,'c'); +CREATE TABLE bb ( +pk INT, +col_varchar_key VARCHAR(1), +PRIMARY KEY (pk), +KEY col_varchar_key (col_varchar_key) +) ENGINE=InnoDB; +INSERT INTO bb VALUES (10,NULL); +SELECT straight_join BIT_AND(c.pk) +FROM +bb, c +WHERE c.col_varchar_key='ABC' +ORDER BY c.pk; +BIT_AND(c.pk) +18446744073709551615 +DROP TABLE c,bb; +# +# Bug #58050: BIT_OR and BIT_XOR return incorrect results when +# semijoin=on +# +CREATE TABLE t1 (pk INT PRIMARY KEY, b INT, c INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 1, 1); +CREATE TABLE t2 (pk INT PRIMARY KEY, b INT, c INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1, 1, NULL); +SELECT t1.* FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1; +pk b c +SELECT BIT_OR(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1; +BIT_OR(t1.b) +0 +SELECT BIT_AND(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1; +BIT_AND(t1.b) +18446744073709551615 +SELECT BIT_XOR(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1; +BIT_XOR(t1.b) +0 +DROP TABLE t1, t2; +End of 5.5 tests diff --git a/mysql-test/t/func_group_innodb.test b/mysql-test/t/func_group_innodb.test index 1bdfd8f54bb..bbc576b0fc7 100644 --- a/mysql-test/t/func_group_innodb.test +++ b/mysql-test/t/func_group_innodb.test @@ -83,3 +83,53 @@ explain select count(*), min(7), max(7) from t2m, t1i; select count(*), min(7), max(7) from t2m, t1i; drop table t1m, t1i, t2m, t2i; + + +--echo # +--echo # Bug #57954: BIT_AND function returns incorrect results when +--echo # semijoin=on + +CREATE TABLE c ( + pk INT, + col_varchar_key VARCHAR(1), + PRIMARY KEY (pk), + KEY col_varchar_key (col_varchar_key) +) ENGINE=InnoDB; +INSERT INTO c VALUES (11,NULL); +INSERT INTO c VALUES (16,'c'); +CREATE TABLE bb ( + pk INT, + col_varchar_key VARCHAR(1), + PRIMARY KEY (pk), + KEY col_varchar_key (col_varchar_key) +) ENGINE=InnoDB; +INSERT INTO bb VALUES (10,NULL); + +SELECT straight_join BIT_AND(c.pk) +FROM + bb, c + WHERE c.col_varchar_key='ABC' +ORDER BY c.pk; + +DROP TABLE c,bb; + +--echo # +--echo # Bug #58050: BIT_OR and BIT_XOR return incorrect results when +--echo # semijoin=on +--echo # + +CREATE TABLE t1 (pk INT PRIMARY KEY, b INT, c INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 1, 1); + +CREATE TABLE t2 (pk INT PRIMARY KEY, b INT, c INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1, 1, NULL); + +SELECT t1.* FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1; +SELECT BIT_OR(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1; +SELECT BIT_AND(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1; +SELECT BIT_XOR(t1.b) FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.pk=1; + +DROP TABLE t1, t2; + + +--echo End of 5.5 tests diff --git a/sql/item_sum.cc b/sql/item_sum.cc index cf95fc3969f..7aff7940c4d 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2235,7 +2235,7 @@ void Item_sum_avg::reset_field() void Item_sum_bit::reset_field() { - reset(); + reset_and_add(); int8store(result_field->ptr, bits); } diff --git a/sql/item_sum.h b/sql/item_sum.h index c7159568c40..3ea79fb8cee 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -406,14 +406,22 @@ public: Item_sum(THD *thd, Item_sum *item); enum Type type() const { return SUM_FUNC_ITEM; } virtual enum Sumfunctype sum_func () const=0; - inline bool reset() { aggregator_clear(); return aggregator_add(); }; + /** + Resets the aggregate value to its default and aggregates the current + value of its attribute(s). + */ + inline bool reset_and_add() + { + aggregator_clear(); + return aggregator_add(); + }; /* Called when new group is started and results are being saved in - a temporary table. Similar to reset(), but must also store value in - result_field. Like reset() it is supposed to reset start value to - default. - This set of methods (reult_field(), reset_field, update_field()) of + a temporary table. Similarly to reset_and_add() it resets the + value to its default and aggregates the value of its + attribute(s), but must also store it in result_field. + This set of methods (result_item(), reset_field, update_field()) of Item_sum is used only if quick_group is not null. Otherwise copy_or_same() is used to obtain a copy of this item. */ @@ -456,7 +464,7 @@ public: set_aggregator(with_distinct ? Aggregator::DISTINCT_AGGREGATOR : Aggregator::SIMPLE_AGGREGATOR); - reset(); + aggregator_clear(); } virtual void make_unique() { force_copy_fields= TRUE; } Item *get_tmp_table_item(THD *thd); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 2ac860d25e3..f39037e9db9 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -11391,7 +11391,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_min_result() min_functions_it->rewind(); while ((min_func= (*min_functions_it)++)) - min_func->reset(); + min_func->reset_and_add(); } @@ -11423,7 +11423,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_max_result() max_functions_it->rewind(); while ((max_func= (*max_functions_it)++)) - max_func->reset(); + max_func->reset_and_add(); } diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index e020c94a3bd..a2f8b9c4447 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -424,7 +424,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) item_sum->aggregator_clear(); } else - item_sum->reset(); + item_sum->reset_and_add(); item_sum->make_const(); recalc_const_item= 1; break; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ef2dd1d76e1..e4772bf3fb2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15850,7 +15850,7 @@ init_sum_functions(Item_sum **func_ptr, Item_sum **end_ptr) { for (; func_ptr != end_ptr ;func_ptr++) { - if ((*func_ptr)->reset()) + if ((*func_ptr)->reset_and_add()) return 1; } /* If rollup, calculate the upper sum levels */ From d7c04a59964dbd4ae237d3d48d316ba470eeeb59 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 9 Dec 2010 12:10:49 +0100 Subject: [PATCH 075/110] Bug #58122 Using DBUG_EXECUTE_IF and normal DBUG printouts not compatible Added option --debug-common which sets 'd' debug flags to the suggested list --- mysql-test/mysql-test-run.pl | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3db8b154fc0..a6179779bf3 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -188,6 +188,8 @@ my $opt_cursor_protocol; my $opt_view_protocol; our $opt_debug; +my $debug_d= "d"; +my $opt_debug_common; our @opt_cases; # The test cases names in argv our $opt_embedded_server; @@ -963,6 +965,7 @@ sub command_line_setup { # Debugging 'debug' => \$opt_debug, + 'debug-common' => \$opt_debug_common, 'gdb' => \$opt_gdb, 'client-gdb' => \$opt_client_gdb, 'manual-gdb' => \$opt_manual_gdb, @@ -1546,6 +1549,18 @@ sub command_line_setup { join(" ", @valgrind_args), "\""); } + if ($opt_debug_common) + { + $opt_debug= 1; + $debug_d= "d,query,info,error,enter,exit"; + } + + if ($opt_debug && $opt_debug ne "1") + { + $debug_d= "d,$opt_debug"; + $debug_d= "d,query,info,error,enter,exit" if $opt_debug eq "std"; + } + mtr_report("Checking supported features..."); check_ndbcluster_support(\%mysqld_variables); @@ -1843,7 +1858,7 @@ sub client_debug_arg($$) { if ( $opt_debug ) { mtr_add_arg($args, - "--debug=d:t:A,%s/log/%s.trace", + "--debug=$debug_d:t:A,%s/log/%s.trace", $path_vardir_trace, $client_name) } } @@ -3008,7 +3023,7 @@ sub mysql_install_db { if ( $opt_debug ) { - mtr_add_arg($args, "--debug=d:t:i:A,%s/log/bootstrap.trace", + mtr_add_arg($args, "--debug=$debug_d:t:i:A,%s/log/bootstrap.trace", $path_vardir_trace); } @@ -4589,7 +4604,7 @@ sub mysqld_start ($$) { if ( $opt_debug ) { - mtr_add_arg($args, "--debug=d:t:i:A,%s/log/%s.trace", + mtr_add_arg($args, "--debug=$debug_d:t:i:A,%s/log/%s.trace", $path_vardir_trace, $mysqld->name()); } @@ -5692,6 +5707,8 @@ Options for debugging the product client-gdb Start mysqltest client in gdb ddd Start mysqld in ddd debug Dump trace output for all servers and client programs + debug-common Same as debug, but sets 'd' debug flags to + "query,info,error,enter,exit" debugger=NAME Start mysqld in the selected debugger gdb Start the mysqld(s) in gdb manual-debug Let user manually start mysqld in debugger, before From 57f7b9f468c278c7cae323b6bd110c125c0ae616 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 9 Dec 2010 12:14:00 +0100 Subject: [PATCH 076/110] Bug #58710 Valgrind warnings in mysqltest Var's string value was not 0-terminated if intially null. While at it, also removed some reported memory leaks Added sanity check, setting val_len=0 if val==0 --- client/mysqltest.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index dfd383cc714..a277af82b13 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -2073,6 +2073,8 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, name_len = strlen(name); if (!val_len && val) val_len = strlen(val) ; + if (!val) + val_len= 0; val_alloc_len = val_len + 16; /* room to grow */ if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var) + name_len+1, MYF(MY_WME)))) @@ -2093,10 +2095,9 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, die("Out of memory"); if (val) - { memcpy(tmp_var->str_val, val, val_len); - tmp_var->str_val[val_len]= 0; - } + tmp_var->str_val[val_len]= 0; + var_check_int(tmp_var); tmp_var->name_len = name_len; tmp_var->str_val_len = val_len; @@ -5053,6 +5054,7 @@ void do_close_connection(struct st_command *command) dynstr_append_mem(ds, ";\n", 2); } + dynstr_free(&ds_connection); DBUG_VOID_RETURN; } @@ -5481,6 +5483,7 @@ void do_connect(struct st_command *command) dynstr_free(&ds_port); dynstr_free(&ds_sock); dynstr_free(&ds_options); + dynstr_free(&ds_default_auth); #ifdef HAVE_SMEM dynstr_free(&ds_shm); #endif @@ -5729,6 +5732,7 @@ void do_block(enum block_cmd cmd, struct st_command* command) } v.is_int= TRUE; + var_free(&v2); } else { if (*expr_start != '`' && ! my_isdigit(charset_info, *expr_start)) @@ -7822,7 +7826,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) ds, &ds_warnings); dynstr_free(&ds_warnings); - if (command->type == Q_EVAL) + if (command->type == Q_EVAL || command->type == Q_SEND_EVAL) dynstr_free(&eval_query); if (display_result_sorted) From 955f42588e0b0d3e739ccef7167c94fff2e9c384 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 9 Dec 2010 12:15:25 +0100 Subject: [PATCH 077/110] Bug #58695 mysqltest coredumps on "if($x == ){" Add check that there is a RHS of the expression Added to mysqltest.test --- client/mysqltest.cc | 2 ++ mysql-test/r/mysqltest.result | 2 ++ mysql-test/t/mysqltest.test | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index a277af82b13..9806d9bed0f 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5680,6 +5680,8 @@ void do_block(enum block_cmd cmd, struct st_command* command) } while (my_isspace(charset_info, *curr_ptr)) curr_ptr++; + if (curr_ptr == expr_end) + die("Missing right operand in comparison"); /* Strip off trailing white space */ while (my_isspace(charset_info, expr_end[-1])) diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 6892164c225..3073dda1154 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -434,6 +434,8 @@ anything goes 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 +mysqltest: At line 1: Missing right operand in comparison +mysqltest: At line 1: Missing right operand in comparison counter is 2 counter is 3 counter is 4 diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 186b0e0fbfa..f7d433c70e8 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1354,6 +1354,11 @@ EOF --exec $MYSQL_TEST < $MYSQL_TMP_DIR/mysqltest.sql 2>&1 remove_file $MYSQL_TMP_DIR/mysqltest.sql; +--error 1 +--exec echo "if (\$var ==) {" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "if (\$var > ) {" | $MYSQL_TEST 2>&1 + # ---------------------------------------------------------------------------- # Test while with compare conditions # ---------------------------------------------------------------------------- From 899a49bcc2efd1598c49c507d548faf048690718 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 9 Dec 2010 14:04:35 +0100 Subject: [PATCH 078/110] Bug #58282 "mtr --mem" does not work on a machine with libaio installed Workaround: add --loose-skip-innodb-use-native-aio Only on linux if explicitly using --mem or setting $OPT_MEM --- mysql-test/mysql-test-run.pl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index a6179779bf3..74fdae1f8c5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3030,6 +3030,12 @@ sub mysql_install_db { mtr_add_arg($args, "--lc-messages-dir=%s", $install_lang); mtr_add_arg($args, "--character-sets-dir=%s", $install_chsdir); + # On some old linux kernels, aio on tmpfs is not supported + # Remove this if/when Bug #58421 fixes this in the server + if ($^O eq "linux" && $opt_mem) { + mtr_add_arg($args, "--loose-skip-innodb-use-native-aio"); + } + # InnoDB arguments that affect file location and sizes may # need to be given to the bootstrap process as well as the # server process. @@ -4515,6 +4521,13 @@ sub mysqld_arguments ($$$) { } } + # On some old linux kernels, aio on tmpfs is not supported + # Remove this if/when Bug #58421 fixes this in the server + if ($^O eq "linux" && $opt_mem) + { + mtr_add_arg($args, "--loose-skip-innodb-use-native-aio"); + } + if ( $mysql_version_id >= 50106 && !$opt_user_args) { # Turn on logging to file From 117237a62e0014297216f256bb868dc77e4ab471 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 9 Dec 2010 14:40:36 +0100 Subject: [PATCH 079/110] Bug #58608 mysqltestrun --help incongruences Fixed some errors Added note about 'no' prefix to options See also follow-up comment to bug report --- mysql-test/mysql-test-run.pl | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 78b7e551918..0d0c1eafb85 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -863,7 +863,7 @@ sub command_line_setup { my $opt_list_options; # Read the command line options - # Note: Keep list, and the order, in sync with usage at end of this file + # Note: Keep list in sync with usage at end of this file Getopt::Long::Configure("pass_through"); my %options=( # Control what engine/variation to run @@ -898,6 +898,7 @@ sub command_line_setup { 'combination=s' => \@opt_combinations, 'skip-combinations' => \&collect_option, 'experimental=s' => \@opt_experimentals, + # skip-im is deprecated and silently ignored 'skip-im' => \&ignore_option, # Specify ports @@ -990,6 +991,7 @@ sub command_line_setup { 'max-connections=i' => \$opt_max_connections, 'help|h' => \$opt_usage, + # list-options is internal, not listed in help 'list-options' => \$opt_list_options, ); @@ -5460,7 +5462,7 @@ Options to control what engine/variation to run defaults-file= Use fixed config template for all tests - defaults_extra_file= Extra config template to add to + defaults-extra-file= Extra config template to add to all generated configs combination= Use at least twice to run tests with specified options to mysqld @@ -5550,7 +5552,7 @@ Options for debugging the product test(s) manual-ddd Let user manually start mysqld in ddd, before running test(s) - strace-client=[path] Create strace output for mysqltest client, optionally + strace-client[=path] Create strace output for mysqltest client, optionally specifying name and path to the trace program to use. Example: $0 --strace-client=ktrace max-save-core Limit the number of core files saved (to avoid filling @@ -5583,7 +5585,7 @@ Options for valgrind Misc options user=USER User for connecting to mysqld(default: $opt_user) comment=STR Write STR to the output - notimer Don't show test case execution time + timer Show test case execution time. verbose More verbose output(use multiple times for even more) verbose-restart Write when and why servers are restarted start Only initialize and start the servers, using the @@ -5623,6 +5625,7 @@ Misc options actions. Disable facility with NUM=0. gcov Collect coverage information after the test. The result is a gcov file per source and header file. + gprof Collect profiling information using gprof. experimental= Refer to list of tests considered experimental; failures will be marked exp-fail instead of fail. report-features First run a "test" that reports mysql features @@ -5631,6 +5634,10 @@ Misc options *previous* test started max-connections=N Max number of open connection to server in mysqltest +Some options that control enabling a feature for normal test runs, +can be turned off by prepending 'no' to the option, e.g. --notimer. +This applies to reorder, timer, check-testcases and warnings. + HERE exit(1); From 83e7edde8761d0d4c7d7da70f7da4888eab6186e Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 9 Dec 2010 14:42:04 +0100 Subject: [PATCH 080/110] Bug #58522 mtr --debug leaks memory when test fails Backported use of setenv() from 5.5 This will remove the leak on systems that have setenv() I have not fixed the string.c leak, it's a local variable that the cleanup function cannot access. --- client/mysqltest.cc | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index fbf4563163b..f7a90dfb8d4 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -73,6 +73,10 @@ #define QUERY_SEND_FLAG 1 #define QUERY_REAP_FLAG 2 +#ifndef HAVE_SETENV +static int setenv(const char *name, const char *value, int overwrite); +#endif + enum { OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION, OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, @@ -219,7 +223,6 @@ typedef struct int alloced_len; int int_dirty; /* do not update string if int is updated until first read */ int alloced; - char *env_s; } VAR; /*Perl/shell-like variable registers */ @@ -1962,7 +1965,7 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, val_len = strlen(val) ; val_alloc_len = val_len + 16; /* room to grow */ if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var) - + name_len+1, MYF(MY_WME)))) + + name_len+2, MYF(MY_WME)))) die("Out of memory"); tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0; @@ -1971,7 +1974,12 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, if (!(tmp_var->str_val = (char*)my_malloc(val_alloc_len+1, MYF(MY_WME)))) die("Out of memory"); - memcpy(tmp_var->name, name, name_len); + if (name) + { + memcpy(tmp_var->name, name, name_len); + tmp_var->name[name_len]= 0; + } + if (val) { memcpy(tmp_var->str_val, val, val_len); @@ -1982,7 +1990,6 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, tmp_var->alloced_len = val_alloc_len; tmp_var->int_val = (val) ? atoi(val) : 0; tmp_var->int_dirty = 0; - tmp_var->env_s = 0; return tmp_var; } @@ -2110,20 +2117,15 @@ void var_set(const char *var_name, const char *var_name_end, if (env_var) { - char buf[1024], *old_env_s= v->env_s; if (v->int_dirty) { sprintf(v->str_val, "%d", v->int_val); v->int_dirty= 0; v->str_val_len= strlen(v->str_val); } - my_snprintf(buf, sizeof(buf), "%.*s=%.*s", - v->name_len, v->name, - v->str_val_len, v->str_val); - if (!(v->env_s= my_strdup(buf, MYF(MY_WME)))) - die("Out of memory"); - putenv(v->env_s); - my_free(old_env_s, MYF(MY_ALLOW_ZERO_PTR)); + /* setenv() expects \0-terminated strings */ + DBUG_ASSERT(v->name[v->name_len] == 0); + setenv(v->name, v->str_val, 1); } DBUG_VOID_RETURN; } @@ -9899,3 +9901,18 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input) delete_dynamic(&lines); DBUG_VOID_RETURN; } + +#ifndef HAVE_SETENV +static int setenv(const char *name, const char *value, int overwrite) +{ + size_t buflen= strlen(name) + strlen(value) + 2; + char *envvar= (char *)malloc(buflen); + if(!envvar) + return ENOMEM; + strcpy(envvar, name); + strcat(envvar, "="); + strcat(envvar, value); + putenv(envvar); + return 0; +} +#endif From bff782d0f0c8a71b826932cb1eec956184c96312 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 9 Dec 2010 14:43:42 +0100 Subject: [PATCH 081/110] Bug #58511 mysqltest doesn't always run statements in ps mode mysqltest checks if the stmt is one that should be run in ps mode, but regexp doesn't match if preceeded by /* */ comment. Fix: match function will jump over /*..*/ if found at start --- client/mysqltest.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index f7a90dfb8d4..9772aa7303d 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -7640,6 +7640,16 @@ void init_re(void) int match_re(my_regex_t *re, char *str) { + while (my_isspace(charset_info, *str)) + str++; + if (str[0] == '/' && str[1] == '*') + { + char *comm_end= strstr (str, "*/"); + if (! comm_end) + die("Statement is unterminated comment"); + str= comm_end + 2; + } + int err= my_regexec(re, str, (size_t)0, NULL, 0); if (err == 0) From dfb622726a7230b00886a183e4189671c27d5dd3 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Fri, 10 Dec 2010 13:48:50 +0600 Subject: [PATCH 082/110] Fixed bug#54486 - assert in my_seek, concurrent DROP/CREATE SCHEMA, CREATE TABLE, REPAIR. The cause of assert was concurrent execution of DROP DATABASE and REPAIR TABLE where first statement deleted table's file .TMD at the same time as REPAIR TABLE tried to read file details from the old file that was just removed. Additionally was fixed trouble when DROP TABLE try delete all files belong to table being dropped at the same time when REPAIR TABLE statement has just deleted .TMD file. No regression test added because this would require adding a sync point to mysys/my_redel.c. Since this bug is not present in 5.5+, adding test coverage was considered unnecessary. The patch has been verified using RQG testing. --- sql/sql_db.cc | 31 +++++++++++++++++++++++-------- storage/myisam/mi_check.c | 2 ++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 2c44c1a8449..d7d7f43a7aa 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -948,9 +948,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) remove_db_from_cache(db); pthread_mutex_unlock(&LOCK_open); - Drop_table_error_handler err_handler(thd->get_internal_handler()); - thd->push_internal_handler(&err_handler); - error= -1; /* We temporarily disable the binary log while dropping the objects @@ -983,8 +980,8 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) error = 0; reenable_binlog(thd); } - thd->pop_internal_handler(); } + if (!silent && deleted>=0) { const char *query; @@ -1213,16 +1210,34 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, else { strxmov(filePath, org_path, "/", file->name, NullS); - if (my_delete_with_symlink(filePath,MYF(MY_WME))) + /* + We ignore ENOENT error in order to skip files that was deleted + by concurrently running statement like REAPIR TABLE ... + */ + if (my_delete_with_symlink(filePath, MYF(0)) && + my_errno != ENOENT) { - goto err; + my_error(EE_DELETE, MYF(0), filePath, my_errno); + goto err; } } } - if (thd->killed || - (tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1))) + + if (thd->killed) goto err; + if (tot_list) + { + int res= 0; + Drop_table_error_handler err_handler(thd->get_internal_handler()); + + thd->push_internal_handler(&err_handler); + res= mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1); + thd->pop_internal_handler(); + if (res) + goto err; + } + /* Remove RAID directories */ { List_iterator it(raid_dirs); diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 8e3864d1c44..935465e7edf 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -1741,6 +1741,8 @@ err: MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || mi_open_datafile(info,share,name,-1)) got_error=1; + + param->retry_repair= 0; } } if (got_error) From 7c36c7e93cd154c8f154a1bc33c9a7557c5caa8d Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Mon, 13 Dec 2010 12:19:30 +0100 Subject: [PATCH 083/110] Bug #58426 Crashing tests not failing as they are supposed to on Solaris 10 debug On this platform we seem to get lots of other signals while waiting for SIGKILL to be delivered. Solution: use sigsuspend() --- dbug/dbug.c | 19 +++++++++++++++++++ include/my_dbug.h | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index fecdd4f8a6c..06a9f7b4bac 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -2276,6 +2276,25 @@ void _db_flush_() } +#ifndef __WIN__ +void _db_suicide_() +{ + int retval; + sigset_t new_mask; + sigfillset(&new_mask); + + fprintf(stderr, "SIGKILL myself\n"); + fflush(stderr); + + retval= kill(getpid(), SIGKILL); + assert(retval == 0); + retval= sigsuspend(&new_mask); + fprintf(stderr, "sigsuspend returned %d errno %d \n", retval, errno); + assert(FALSE); /* With full signal mask, we should never return here. */ +} +#endif /* ! __WIN__ */ + + void _db_lock_file_() { CODE_STATE *cs=0; diff --git a/include/my_dbug.h b/include/my_dbug.h index f08e94a1882..1ae9a50c76d 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -160,7 +160,8 @@ extern void _db_flush_(); #ifdef __WIN__ #define DBUG_SUICIDE() DBUG_ABORT() #else -#define DBUG_SUICIDE() (_db_flush_(), kill(getpid(), SIGKILL), pause()) +extern void _db_suicide_(); +#define DBUG_SUICIDE() (_db_flush_(), _db_suicide_()) #endif #else /* No debugger */ From 9b6ba6a99aa353efd2da8dc8493aa932cc7523c2 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 14 Dec 2010 17:34:23 +0300 Subject: [PATCH 084/110] WL#5571 - Audit interface: MYSQL_AUDIT_GENERAL_STATUS event --- include/mysql/plugin_audit.h | 40 ++++++++++++++++++++++++++++++++ include/mysql/plugin_audit.h.pp | 21 +++++++++++++++++ sql/mysqld.cc | 1 + sql/sql_audit.cc | 27 +++++++++++++++++++++- sql/sql_audit.h | 41 +++++++++++++++++++++++++++++++++ sql/sql_connect.cc | 5 +++- sql/sql_parse.cc | 9 +++++++- 7 files changed, 141 insertions(+), 3 deletions(-) diff --git a/include/mysql/plugin_audit.h b/include/mysql/plugin_audit.h index 41505da64af..8811c832949 100644 --- a/include/mysql/plugin_audit.h +++ b/include/mysql/plugin_audit.h @@ -42,6 +42,8 @@ struct mysql_event LOG events occurs before emitting to the general query log. ERROR events occur before transmitting errors to the user. RESULT events occur after transmitting a resultset to the user. + STATUS events occur after transmitting a resultset or errors + to the user. */ #define MYSQL_AUDIT_GENERAL_CLASS 0 @@ -49,6 +51,7 @@ struct mysql_event #define MYSQL_AUDIT_GENERAL_LOG 0 #define MYSQL_AUDIT_GENERAL_ERROR 1 #define MYSQL_AUDIT_GENERAL_RESULT 2 +#define MYSQL_AUDIT_GENERAL_STATUS 3 struct mysql_event_general { @@ -68,6 +71,43 @@ struct mysql_event_general }; +/* + AUDIT CLASS : CONNECTION + + CONNECT occurs after authentication phase is completed. + DISCONNECT occurs after connection is terminated. + CHANGE_USER occurs after COM_CHANGE_USER RPC is completed. +*/ + +#define MYSQL_AUDIT_CONNECTION_CLASS 1 +#define MYSQL_AUDIT_CONNECTION_CLASSMASK (1 << MYSQL_AUDIT_CONNECTION_CLASS) +#define MYSQL_AUDIT_CONNECTION_CONNECT 0 +#define MYSQL_AUDIT_CONNECTION_DISCONNECT 1 +#define MYSQL_AUDIT_CONNECTION_CHANGE_USER 2 + +struct mysql_event_connection +{ + unsigned int event_class; + unsigned int event_subclass; + int status; + unsigned long thread_id; + const char *user; + unsigned int user_length; + const char *priv_user; + unsigned int priv_user_length; + const char *external_user; + unsigned int external_user_length; + const char *proxy_user; + unsigned int proxy_user_length; + const char *host; + unsigned int host_length; + const char *ip; + unsigned int ip_length; + const char *database; + unsigned int database_length; +}; + + /************************************************************************* Here we define the descriptor structure, that is referred from st_mysql_plugin. diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index b48cbca2e87..0e5b97d8717 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -208,6 +208,27 @@ struct mysql_event_general unsigned long long general_time; unsigned long long general_rows; }; +struct mysql_event_connection +{ + unsigned int event_class; + unsigned int event_subclass; + int status; + unsigned long thread_id; + const char *user; + unsigned int user_length; + const char *priv_user; + unsigned int priv_user_length; + const char *external_user; + unsigned int external_user_length; + const char *proxy_user; + unsigned int proxy_user_length; + const char *host; + unsigned int host_length; + const char *ip; + unsigned int ip_length; + const char *database; + unsigned int database_length; +}; struct st_mysql_audit { int interface_version; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 49523a5b007..5fb63fb61ba 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1992,6 +1992,7 @@ void close_connection(THD *thd, uint errcode, bool lock) { sleep(0); /* Workaround to avoid tailcall optimisation */ } + MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, errcode); DBUG_VOID_RETURN; } #endif /* EMBEDDED_LIBRARY */ diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc index b7d363dc09a..74e9e603ebe 100644 --- a/sql/sql_audit.cc +++ b/sql/sql_audit.cc @@ -81,9 +81,34 @@ static void general_class_handler(THD *thd, uint event_subtype, va_list ap) } +static void connection_class_handler(THD *thd, uint event_subclass, va_list ap) +{ + mysql_event_connection event; + event.event_class= MYSQL_AUDIT_CONNECTION_CLASS; + event.event_subclass= event_subclass; + event.status= va_arg(ap, int); + event.thread_id= va_arg(ap, unsigned long); + event.user= va_arg(ap, const char *); + event.user_length= va_arg(ap, unsigned int); + event.priv_user= va_arg(ap, const char *); + event.priv_user_length= va_arg(ap, unsigned int); + event.external_user= va_arg(ap, const char *); + event.external_user_length= va_arg(ap, unsigned int); + event.proxy_user= va_arg(ap, const char *); + event.proxy_user_length= va_arg(ap, unsigned int); + event.host= va_arg(ap, const char *); + event.host_length= va_arg(ap, unsigned int); + event.ip= va_arg(ap, const char *); + event.ip_length= va_arg(ap, unsigned int); + event.database= va_arg(ap, const char *); + event.database_length= va_arg(ap, unsigned int); + event_class_dispatch(thd, (const mysql_event *) &event); +} + + static audit_handler_t audit_handlers[] = { - general_class_handler + general_class_handler, connection_class_handler }; static const uint audit_handlers_count= diff --git a/sql/sql_audit.h b/sql/sql_audit.h index cbc4c7a7232..d676c3974bc 100644 --- a/sql/sql_audit.h +++ b/sql/sql_audit.h @@ -32,8 +32,12 @@ extern void mysql_audit_free_thd(THD *thd); extern void mysql_audit_acquire_plugins(THD *thd, uint event_class); +#ifndef EMBEDDED_LIBRARY extern void mysql_audit_notify(THD *thd, uint event_class, uint event_subtype, ...); +#else +#define mysql_audit_notify(...) +#endif extern void mysql_audit_release(THD *thd); #define MAX_USER_HOST_SIZE 512 @@ -84,6 +88,7 @@ void mysql_audit_general_log(THD *thd, time_t time, event_subtype should be set to one of: MYSQL_AUDIT_GENERAL_ERROR MYSQL_AUDIT_GENERAL_RESULT + MYSQL_AUDIT_GENERAL_STATUS @param[in] thd @param[in] event_subtype Type of general audit event. @@ -126,5 +131,41 @@ void mysql_audit_general(THD *thd, uint event_subtype, #endif } +#define MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd) mysql_audit_notify(\ + (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CONNECT,\ + (thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\ + (thd)->thread_id, (thd)->security_ctx->user,\ + (thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\ + (thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\ + (thd)->security_ctx->external_user,\ + (thd)->security_ctx->external_user ?\ + strlen((thd)->security_ctx->external_user) : 0,\ + (thd)->security_ctx->proxy_user, strlen((thd)->security_ctx->proxy_user),\ + (thd)->security_ctx->host,\ + (thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\ + (thd)->security_ctx->ip,\ + (thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\ + (thd)->db, (thd)->db ? strlen((thd)->db) : 0) + +#define MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, errcode)\ + mysql_audit_notify(\ + (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_DISCONNECT,\ + (errcode), (thd)->thread_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +#define MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd) mysql_audit_notify(\ + (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CHANGE_USER,\ + (thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\ + (thd)->thread_id, (thd)->security_ctx->user,\ + (thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\ + (thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\ + (thd)->security_ctx->external_user,\ + (thd)->security_ctx->external_user ?\ + strlen((thd)->security_ctx->external_user) : 0,\ + (thd)->security_ctx->proxy_user, strlen((thd)->security_ctx->proxy_user),\ + (thd)->security_ctx->host,\ + (thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\ + (thd)->security_ctx->ip,\ + (thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\ + (thd)->db, (thd)->db ? strlen((thd)->db) : 0) #endif /* SQL_AUDIT_INCLUDED */ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index d03d77c1f66..a47493b7d0d 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -728,9 +728,12 @@ void do_handle_one_connection(THD *thd_arg) for (;;) { NET *net= &thd->net; + bool rc; lex_start(thd); - if (login_connection(thd)) + rc= login_connection(thd); + MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd); + if (rc) goto end_thread; MYSQL_CONNECTION_START(thd->thread_id, thd->security_ctx->priv_user, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3d5f99c8953..cdeaeee18c1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -937,6 +937,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif case COM_CHANGE_USER: { + bool rc; status_var_increment(thd->status_var.com_other); thd->change_user(); @@ -956,7 +957,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, CHARSET_INFO *save_character_set_results= thd->variables.character_set_results; - if (acl_authenticate(thd, 0, packet_length)) + rc= acl_authenticate(thd, 0, packet_length); + MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd); + if (rc) { my_free(thd->security_ctx->user); *thd->security_ctx= save_security_ctx; @@ -1395,6 +1398,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (!thd->is_error() && !thd->killed_errno()) mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0); + mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS, + thd->stmt_da->is_error() ? thd->stmt_da->sql_errno() : 0, + command_name[command].str); + log_slow_statement(thd); thd_proc_info(thd, "cleaning up"); From 961cada835e53c32a03e45eff4309be728810632 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 8 Dec 2010 18:47:21 +0200 Subject: [PATCH 085/110] Bug #58350: 5.5.7-rc compile failed at sp_head.cc Fixed the references to security_ctx->priv_user to be real char * pointers instead of a C array name reference. This is somehow important for some 3d party dtrace replacements --- sql/sp_head.cc | 2 +- sql/sql_connect.cc | 2 +- sql/sql_cursor.cc | 2 +- sql/sql_parse.cc | 8 ++++---- sql/sql_prepare.cc | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 2f165310c28..6017541266b 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3159,7 +3159,7 @@ sp_instr_stmt::exec_core(THD *thd, uint *nextp) MYSQL_QUERY_EXEC_START(thd->query(), thd->thread_id, (char *) (thd->db ? thd->db : ""), - thd->security_ctx->priv_user, + &thd->security_ctx->priv_user[0], (char *)thd->security_ctx->host_or_ip, 3); int res= mysql_execute_command(thd); diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index a47493b7d0d..9799ae14b2f 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -736,7 +736,7 @@ void do_handle_one_connection(THD *thd_arg) if (rc) goto end_thread; - MYSQL_CONNECTION_START(thd->thread_id, thd->security_ctx->priv_user, + MYSQL_CONNECTION_START(thd->thread_id, &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip); prepare_new_connection_state(thd); diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index acc591f1ea2..f607936d5b9 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -111,7 +111,7 @@ int mysql_open_cursor(THD *thd, select_result *result, MYSQL_QUERY_EXEC_START(thd->query(), thd->thread_id, (char *) (thd->db ? thd->db : ""), - thd->security_ctx->priv_user, + &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip, 2); rc= mysql_execute_command(thd); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index cdeaeee18c1..dff6510817f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -877,7 +877,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->profiling.start_new_query(); #endif MYSQL_COMMAND_START(thd->thread_id, command, - thd->security_ctx->priv_user, + &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip); thd->command=command; @@ -1018,7 +1018,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; // fatal error is set MYSQL_QUERY_START(thd->query(), thd->thread_id, (char *) (thd->db ? thd->db : ""), - thd->security_ctx->priv_user, + &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip); char *packet_end= thd->query() + thd->query_length(); /* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */ @@ -1070,7 +1070,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, MYSQL_QUERY_START(beginning_of_next_stmt, thd->thread_id, (char *) (thd->db ? thd->db : ""), - thd->security_ctx->priv_user, + &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip); thd->set_query_and_id(beginning_of_next_stmt, length, @@ -5489,7 +5489,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, MYSQL_QUERY_EXEC_START(thd->query(), thd->thread_id, (char *) (thd->db ? thd->db : ""), - thd->security_ctx->priv_user, + &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip, 0); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 345f7158dbf..f319c0fdd8b 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3759,7 +3759,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) MYSQL_QUERY_EXEC_START(thd->query(), thd->thread_id, (char *) (thd->db ? thd->db : ""), - thd->security_ctx->priv_user, + &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip, 1); error= mysql_execute_command(thd); From cc1288349f7af7937d30921d80d761889e88e9b6 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Thu, 9 Dec 2010 12:59:12 +0300 Subject: [PATCH 086/110] Fix for bug#48451: my_seek and my_tell ignore MY_WME flag my_seek() and my_tell() functions now honour MY_WME flag. --- include/mysys_err.h | 3 ++- mysys/errors.c | 2 ++ mysys/my_seek.c | 13 ++++++++++--- mysys/my_symlink.c | 3 +-- storage/myisam/ha_myisam.cc | 12 ++++++++++-- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/include/mysys_err.h b/include/mysys_err.h index 6294b37f773..a902c178772 100644 --- a/include/mysys_err.h +++ b/include/mysys_err.h @@ -64,7 +64,8 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */ #define EE_FILE_NOT_CLOSED 30 #define EE_CHANGE_OWNERSHIP 31 #define EE_CHANGE_PERMISSIONS 32 -#define EE_ERROR_LAST 32 /* Copy last error nr */ +#define EE_CANT_SEEK 33 +#define EE_ERROR_LAST 33 /* Copy last error nr */ /* Add error numbers before EE_ERROR_LAST and change it accordingly. */ /* exit codes for all MySQL programs */ diff --git a/mysys/errors.c b/mysys/errors.c index a5ad4a956ab..da9f3122a19 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -52,6 +52,7 @@ const char * NEAR globerrs[GLOBERRS]= "File '%s' (fileno: %d) was not closed", "Can't change ownership of the file '%s' (Errcode: %d)", "Can't change permissions of the file '%s' (Errcode: %d)", + "Can't seek in file '%s' (Errcode: %d)" }; void init_glob_errs(void) @@ -94,6 +95,7 @@ void init_glob_errs() EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed"; EE(EE_CHANGE_OWNERSHIP) = "Can't change ownership of the file '%s' (Errcode: %d)"; EE(EE_CHANGE_PERMISSIONS) = "Can't change permissions of the file '%s' (Errcode: %d)"; + EE(EE_CANT_SEEK) = "Can't seek in file '%s' (Errcode: %d)"; } #endif diff --git a/mysys/my_seek.c b/mysys/my_seek.c index 2c661baeff7..830c2ba245d 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -14,6 +14,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mysys_priv.h" +#include "mysys_err.h" /* Seek to a position in a file. @@ -42,8 +43,7 @@ actual error. */ -my_off_t my_seek(File fd, my_off_t pos, int whence, - myf MyFlags __attribute__((unused))) +my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags) { reg1 os_off_t newpos= -1; DBUG_ENTER("my_seek"); @@ -69,6 +69,8 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, if (newpos == (os_off_t) -1) { my_errno=errno; + if (MyFlags & MY_WME) + my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno); DBUG_PRINT("error",("lseek: %lu errno: %d", (ulong) newpos,errno)); DBUG_RETURN(MY_FILEPOS_ERROR); } @@ -83,7 +85,7 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, /* Tell current position of file */ /* ARGSUSED */ -my_off_t my_tell(File fd, myf MyFlags __attribute__((unused))) +my_off_t my_tell(File fd, myf MyFlags) { os_off_t pos; DBUG_ENTER("my_tell"); @@ -95,7 +97,12 @@ my_off_t my_tell(File fd, myf MyFlags __attribute__((unused))) pos=lseek(fd, 0L, MY_SEEK_CUR); #endif if (pos == (os_off_t) -1) + { my_errno=errno; + if (MyFlags & MY_WME) + my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno); + DBUG_PRINT("error", ("tell: %lu errno: %d", (ulong) pos, my_errno)); + } DBUG_PRINT("exit",("pos: %lu", (ulong) pos)); DBUG_RETURN((my_off_t) pos); } /* my_tell */ diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index b57edd2179a..59d929f9a61 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -118,8 +118,7 @@ int my_is_symlink(const char *filename __attribute__((unused))) 'to' may be equal to 'filename' */ -int my_realpath(char *to, const char *filename, - myf MyFlags __attribute__((unused))) +int my_realpath(char *to, const char *filename, myf MyFlags) { #if defined(HAVE_REALPATH) && !defined(HAVE_BROKEN_REALPATH) int result=0; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 12557b75cc1..2650cc850a8 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -590,7 +590,11 @@ int ha_myisam::net_read_dump(NET* net) int data_fd = file->dfile; int error = 0; - my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME)); + if (my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME)) == MY_FILEPOS_ERROR) + { + error= my_errno; + goto err; + } for (;;) { ulong packet_len = my_net_read(net); @@ -626,7 +630,11 @@ int ha_myisam::dump(THD* thd, int fd) return ENOMEM; int error = 0; - my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME)); + if (my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME)) == MY_FILEPOS_ERROR) + { + error= my_errno; + goto err; + } for (; bytes_to_read > 0;) { size_t bytes = my_read(data_fd, buf, blocksize, MYF(MY_WME)); From eef6603f9ed2a3b418214fd004ab825e19d663fc Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Thu, 9 Dec 2010 15:04:58 +0100 Subject: [PATCH 087/110] Bug#58831: large_tests.alter_table crashes the server The tests generates 4 Billion rows which timeouts. Removed the test from the default weekly run. --- mysql-test/collections/default.weekly | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/collections/default.weekly b/mysql-test/collections/default.weekly index 5865864f4cd..92750cca166 100644 --- a/mysql-test/collections/default.weekly +++ b/mysql-test/collections/default.weekly @@ -1,2 +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 +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 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 From 4096f35a395cee270218ae220b921af567ae26da Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 13 Dec 2010 13:39:26 +0300 Subject: [PATCH 088/110] Bug#58396 group_concat and explain extended are still crashy Explain fails at fix_fields stage and some items are left unfixed, particulary Item_group_concat. Item_group_concat::orig_args field is uninitialized in this case and Item_group_concat::print call leads to crash. The fix: move the initialization of Item_group_concat::orig_args into constructor. --- mysql-test/r/func_gconcat.result | 12 ++++++++++++ mysql-test/t/func_gconcat.test | 11 +++++++++++ sql/item_sum.cc | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index de592ece285..4a79a15a2b6 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -1037,4 +1037,16 @@ 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; +# +# Bug#58396 group_concat and explain extended are still crashy +# +CREATE TABLE t1(a INT); +EXPLAIN EXTENDED SELECT UPDATEXML('1', a, '1') +FROM t1 ORDER BY (SELECT GROUP_CONCAT(1) FROM t1); +ERROR HY000: Only constant XPATH queries are supported +SHOW WARNINGS; +Level Code Message +Error 1105 Only constant XPATH queries are supported +Note 1003 select updatexml('1',`test`.`t1`.`a`,'1') AS `UPDATEXML('1', a, '1')` from `test`.`t1` order by (select group_concat(1 separator ',') from `test`.`t1`) +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 a7072362759..1475ca082a5 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -746,4 +746,15 @@ SELECT POLYGON((SELECT 1 FROM (SELECT 1 IN (GROUP_CONCAT(t1.f1)) FROM t1, t1 t G --enable_ps_protocol DROP TABLE t1; +--echo # +--echo # Bug#58396 group_concat and explain extended are still crashy +--echo # + +CREATE TABLE t1(a INT); +--error ER_UNKNOWN_ERROR +EXPLAIN EXTENDED SELECT UPDATEXML('1', a, '1') +FROM t1 ORDER BY (SELECT GROUP_CONCAT(1) FROM t1); +SHOW WARNINGS; +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 65f8222d38b..a60a6b3ef95 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3003,6 +3003,7 @@ Item_func_group_concat(Name_resolution_context *context_arg, order_item->item= arg_ptr++; } } + memcpy(orig_args, args, sizeof(Item*) * arg_count); } @@ -3233,7 +3234,6 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) if (check_sum_func(thd, ref)) return TRUE; - memcpy (orig_args, args, sizeof (Item *) * arg_count); fixed= 1; return FALSE; } From 0e77c3295a83eaaf3ac37e13c4d2c7a467add12e Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 13 Dec 2010 14:48:12 +0300 Subject: [PATCH 089/110] Bug#39828 : Autoinc wraps around when offset and increment > 1 Auto increment value wraps when performing a bulk insert with auto_increment_increment and auto_increment_offset greater than one. The fix: If overflow happened then return MAX_ULONGLONG value as an indication of overflow and check this before storing the value into the field in update_auto_increment(). --- mysql-test/r/auto_increment.result | 21 ++++++++ .../suite/innodb/r/innodb-autoinc.result | 18 +++---- mysql-test/suite/innodb/t/innodb-autoinc.test | 49 +++---------------- .../innodb_plugin/r/innodb-autoinc.result | 18 +++---- .../suite/innodb_plugin/t/innodb-autoinc.test | 49 +++---------------- mysql-test/t/auto_increment.test | 21 ++++++++ sql/handler.cc | 30 +++++++++--- 7 files changed, 88 insertions(+), 118 deletions(-) diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index 4a2e108f8c6..5fae14e2c07 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -476,3 +476,24 @@ SELECT a FROM t2; a 2 DROP TABLE t1, t2; +# +# Bug#39828 autoinc wraps around when offset and increment > 1 +# +CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) engine=MyISAM; +INSERT INTO t1 VALUES(1); +INSERT INTO t1 VALUES (18446744073709551601); +SET @@SESSION.AUTO_INCREMENT_INCREMENT=10; +SELECT @@SESSION.AUTO_INCREMENT_OFFSET; +@@SESSION.AUTO_INCREMENT_OFFSET +1 +INSERT INTO t1 VALUES (NULL), (NULL), (NULL); +ERROR 22003: Out of range value for column 't1' at row 167 +SELECT * FROM t1; +c1 +1 +18446744073709551601 +18446744073709551611 +SET @@SESSION.AUTO_INCREMENT_INCREMENT=default; +SET @@SESSION.AUTO_INCREMENT_OFFSET=default; +DROP TABLE t1; +End of 5.1 tests diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result index 350c7ebd541..0c8d16f27fb 100644 --- a/mysql-test/suite/innodb/r/innodb-autoinc.result +++ b/mysql-test/suite/innodb/r/innodb-autoinc.result @@ -471,17 +471,12 @@ SHOW VARIABLES LIKE "%auto_inc%"; Variable_name Value auto_increment_increment 2 auto_increment_offset 10 -INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL); +INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine SELECT * FROM t1; c1 1 18446744073709551603 -18446744073709551604 -18446744073709551606 -18446744073709551608 -18446744073709551610 -18446744073709551612 -18446744073709551614 DROP TABLE t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; SET @@INSERT_ID=1; @@ -504,13 +499,12 @@ SHOW VARIABLES LIKE "%auto_inc%"; Variable_name Value auto_increment_increment 5 auto_increment_offset 7 -INSERT INTO t1 VALUES (NULL),(NULL); +INSERT INTO t1 VALUES (NULL),(NULL), (NULL); +ERROR HY000: Failed to read auto-increment value from storage engine SELECT * FROM t1; c1 1 18446744073709551603 -18446744073709551607 -18446744073709551612 DROP TABLE t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; SET @@INSERT_ID=1; @@ -572,12 +566,12 @@ SHOW VARIABLES LIKE "%auto_inc%"; Variable_name Value auto_increment_increment 65535 auto_increment_offset 65535 -INSERT INTO t1 VALUES (NULL); +INSERT INTO t1 VALUES (NULL),(NULL); +ERROR 22003: Out of range value for column 't1' at row 167 SELECT * FROM t1; c1 1 18446744073709551610 -18446744073709551615 DROP TABLE t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; SET @@INSERT_ID=1; diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test index 10602499222..c3b64c7c963 100644 --- a/mysql-test/suite/innodb/t/innodb-autoinc.test +++ b/mysql-test/suite/innodb/t/innodb-autoinc.test @@ -291,21 +291,8 @@ INSERT INTO t1 VALUES (18446744073709551603); #-- 2^64 - 13 SELECT * FROM t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10; SHOW VARIABLES LIKE "%auto_inc%"; -# This should fail because of overflow but it doesn't, it seems to be -# a MySQL server bug. It wraps around to 0 for the last value. -# See MySQL Bug# 39828 -# -# Instead of wrapping around, it asserts when MySQL is compiled --with-debug -# (see sql/handler.cc:handler::update_auto_increment()). Don't test for -# overflow until Bug #39828 is fixed. -# -# Since this asserts when compiled --with-debug, we can't properly test this -# until Bug #39828 is fixed. For now, this test is meaningless. -#if Bug #39828 is fixed -#INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL); -#else -INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL); -#endif +--error ER_AUTOINC_READ_FAILED +INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL); SELECT * FROM t1; DROP TABLE t1; @@ -323,20 +310,8 @@ INSERT INTO t1 VALUES (18446744073709551603); #-- 2^64 - 13 SELECT * FROM t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7; SHOW VARIABLES LIKE "%auto_inc%"; -# This should fail because of overflow but it doesn't. It fails with -# a duplicate entry message because of a MySQL server bug, it wraps -# around. See MySQL Bug# 39828, once MySQL fix the bug we can replace -# the ER_DUP_ENTRY, 1062 below with the appropriate error message -# -# Since this asserts when compiled --with-debug, we can't properly test this -# until Bug #39828 is fixed. For now, this test is meaningless. -#if Bug #39828 is fixed -# Still need to fix this error code, error should mention overflow -#-- error ER_DUP_ENTRY,1062 -#INSERT INTO t1 VALUES (NULL),(NULL), (NULL); -#else -INSERT INTO t1 VALUES (NULL),(NULL); -#endif +--error ER_AUTOINC_READ_FAILED +INSERT INTO t1 VALUES (NULL),(NULL), (NULL); SELECT * FROM t1; DROP TABLE t1; @@ -374,20 +349,8 @@ INSERT INTO t1 VALUES (18446744073709551610); #-- 2^64 - 2 SELECT * FROM t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976; SHOW VARIABLES LIKE "%auto_inc%"; -# This should fail because of overflow but it doesn't. It wraps around -# and the autoinc values look bogus too. -# See MySQL Bug# 39828, once MySQL fix the bug we can enable the error -# code expected test. -# -- error ER_AUTOINC_READ_FAILED,1467 -# -# Since this asserts when compiled --with-debug, we can't properly test this -# until Bug #39828 is fixed. For now, this test is meaningless. -#if Bug #39828 is fixed -#-- error ER_AUTOINC_READ_FAILED,1467 -#INSERT INTO t1 VALUES (NULL),(NULL); -#else -INSERT INTO t1 VALUES (NULL); -#endif +--error ER_WARN_DATA_OUT_OF_RANGE +INSERT INTO t1 VALUES (NULL),(NULL); SELECT * FROM t1; DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result b/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result index 350c7ebd541..0c8d16f27fb 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result @@ -471,17 +471,12 @@ SHOW VARIABLES LIKE "%auto_inc%"; Variable_name Value auto_increment_increment 2 auto_increment_offset 10 -INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL); +INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine SELECT * FROM t1; c1 1 18446744073709551603 -18446744073709551604 -18446744073709551606 -18446744073709551608 -18446744073709551610 -18446744073709551612 -18446744073709551614 DROP TABLE t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; SET @@INSERT_ID=1; @@ -504,13 +499,12 @@ SHOW VARIABLES LIKE "%auto_inc%"; Variable_name Value auto_increment_increment 5 auto_increment_offset 7 -INSERT INTO t1 VALUES (NULL),(NULL); +INSERT INTO t1 VALUES (NULL),(NULL), (NULL); +ERROR HY000: Failed to read auto-increment value from storage engine SELECT * FROM t1; c1 1 18446744073709551603 -18446744073709551607 -18446744073709551612 DROP TABLE t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; SET @@INSERT_ID=1; @@ -572,12 +566,12 @@ SHOW VARIABLES LIKE "%auto_inc%"; Variable_name Value auto_increment_increment 65535 auto_increment_offset 65535 -INSERT INTO t1 VALUES (NULL); +INSERT INTO t1 VALUES (NULL),(NULL); +ERROR 22003: Out of range value for column 't1' at row 167 SELECT * FROM t1; c1 1 18446744073709551610 -18446744073709551615 DROP TABLE t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; SET @@INSERT_ID=1; diff --git a/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test b/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test index 997c503d2d3..4967a6efbb9 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test +++ b/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test @@ -293,21 +293,8 @@ INSERT INTO t1 VALUES (18446744073709551603); #-- 2^64 - 13 SELECT * FROM t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10; SHOW VARIABLES LIKE "%auto_inc%"; -# This should fail because of overflow but it doesn't, it seems to be -# a MySQL server bug. It wraps around to 0 for the last value. -# See MySQL Bug# 39828 -# -# Instead of wrapping around, it asserts when MySQL is compiled --with-debug -# (see sql/handler.cc:handler::update_auto_increment()). Don't test for -# overflow until Bug #39828 is fixed. -# -# Since this asserts when compiled --with-debug, we can't properly test this -# until Bug #39828 is fixed. For now, this test is meaningless. -#if Bug #39828 is fixed -#INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL); -#else -INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL); -#endif +--error ER_AUTOINC_READ_FAILED +INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL); SELECT * FROM t1; DROP TABLE t1; @@ -325,20 +312,8 @@ INSERT INTO t1 VALUES (18446744073709551603); #-- 2^64 - 13 SELECT * FROM t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7; SHOW VARIABLES LIKE "%auto_inc%"; -# This should fail because of overflow but it doesn't. It fails with -# a duplicate entry message because of a MySQL server bug, it wraps -# around. See MySQL Bug# 39828, once MySQL fix the bug we can replace -# the ER_DUP_ENTRY, 1062 below with the appropriate error message -# -# Since this asserts when compiled --with-debug, we can't properly test this -# until Bug #39828 is fixed. For now, this test is meaningless. -#if Bug #39828 is fixed -# Still need to fix this error code, error should mention overflow -#-- error ER_DUP_ENTRY,1062 -#INSERT INTO t1 VALUES (NULL),(NULL), (NULL); -#else -INSERT INTO t1 VALUES (NULL),(NULL); -#endif +--error ER_AUTOINC_READ_FAILED +INSERT INTO t1 VALUES (NULL),(NULL), (NULL); SELECT * FROM t1; DROP TABLE t1; @@ -376,20 +351,8 @@ INSERT INTO t1 VALUES (18446744073709551610); #-- 2^64 - 2 SELECT * FROM t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976; SHOW VARIABLES LIKE "%auto_inc%"; -# This should fail because of overflow but it doesn't. It wraps around -# and the autoinc values look bogus too. -# See MySQL Bug# 39828, once MySQL fix the bug we can enable the error -# code expected test. -# -- error ER_AUTOINC_READ_FAILED,1467 -# -# Since this asserts when compiled --with-debug, we can't properly test this -# until Bug #39828 is fixed. For now, this test is meaningless. -#if Bug #39828 is fixed -#-- error ER_AUTOINC_READ_FAILED,1467 -#INSERT INTO t1 VALUES (NULL),(NULL); -#else -INSERT INTO t1 VALUES (NULL); -#endif +--error ER_WARN_DATA_OUT_OF_RANGE +INSERT INTO t1 VALUES (NULL),(NULL); SELECT * FROM t1; DROP TABLE t1; diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index 076e32eb22c..8ab2e6fcf31 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -342,3 +342,24 @@ SELECT a FROM t2; DROP TABLE t1, t2; +--echo # +--echo # Bug#39828 autoinc wraps around when offset and increment > 1 +--echo # + +CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) engine=MyISAM; +INSERT INTO t1 VALUES(1); +INSERT INTO t1 VALUES (18446744073709551601); + +SET @@SESSION.AUTO_INCREMENT_INCREMENT=10; + +SELECT @@SESSION.AUTO_INCREMENT_OFFSET; +--error ER_WARN_DATA_OUT_OF_RANGE +INSERT INTO t1 VALUES (NULL), (NULL), (NULL); +SELECT * FROM t1; + +SET @@SESSION.AUTO_INCREMENT_INCREMENT=default; +SET @@SESSION.AUTO_INCREMENT_OFFSET=default; + +DROP TABLE t1; + +--echo End of 5.1 tests diff --git a/sql/handler.cc b/sql/handler.cc index 1525ca53bca..33c7f518838 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2166,7 +2166,8 @@ int handler::read_first_row(uchar * buf, uint primary_key) computes the lowest number - strictly greater than "nr" - of the form: auto_increment_offset + N * auto_increment_increment - + If overflow happened then return MAX_ULONGLONG value as an + indication of overflow. In most cases increment= offset= 1, in which case we get: @verbatim 1,2,3,4,5,... @endverbatim If increment=10 and offset=5 and previous number is 1, we get: @@ -2175,13 +2176,23 @@ int handler::read_first_row(uchar * buf, uint primary_key) inline ulonglong compute_next_insert_id(ulonglong nr,struct system_variables *variables) { + const ulonglong save_nr= nr; + if (variables->auto_increment_increment == 1) - return (nr+1); // optimization of the formula below - nr= (((nr+ variables->auto_increment_increment - - variables->auto_increment_offset)) / - (ulonglong) variables->auto_increment_increment); - return (nr* (ulonglong) variables->auto_increment_increment + - variables->auto_increment_offset); + nr= nr + 1; // optimization of the formula below + else + { + nr= (((nr+ variables->auto_increment_increment - + variables->auto_increment_offset)) / + (ulonglong) variables->auto_increment_increment); + nr= (nr* (ulonglong) variables->auto_increment_increment + + variables->auto_increment_offset); + } + + if (unlikely(nr <= save_nr)) + return ULONGLONG_MAX; + + return nr; } @@ -2392,7 +2403,7 @@ int handler::update_auto_increment() variables->auto_increment_increment, nb_desired_values, &nr, &nb_reserved_values); - if (nr == ~(ulonglong) 0) + if (nr == ULONGLONG_MAX) DBUG_RETURN(HA_ERR_AUTOINC_READ_FAILED); // Mark failure /* @@ -2423,6 +2434,9 @@ int handler::update_auto_increment() } } + if (unlikely(nr == ULONGLONG_MAX)) + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + DBUG_PRINT("info",("auto_increment: %lu", (ulong) nr)); if (unlikely(table->next_number_field->store((longlong) nr, TRUE))) From fcd44f727dc5f6c6e92517d190018e2221fd4ff4 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Mon, 13 Dec 2010 17:13:01 +0100 Subject: [PATCH 090/110] Bug #58426 Crashing tests not failing as they are supposed to on Solaris 10 debug On this platform we seem to get lots of other signals while waiting for SIGKILL to be delivered. Solution: use sigsuspend() --- dbug/dbug.c | 19 +++++++++++++++++++ include/my_dbug.h | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index fecdd4f8a6c..06a9f7b4bac 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -2276,6 +2276,25 @@ void _db_flush_() } +#ifndef __WIN__ +void _db_suicide_() +{ + int retval; + sigset_t new_mask; + sigfillset(&new_mask); + + fprintf(stderr, "SIGKILL myself\n"); + fflush(stderr); + + retval= kill(getpid(), SIGKILL); + assert(retval == 0); + retval= sigsuspend(&new_mask); + fprintf(stderr, "sigsuspend returned %d errno %d \n", retval, errno); + assert(FALSE); /* With full signal mask, we should never return here. */ +} +#endif /* ! __WIN__ */ + + void _db_lock_file_() { CODE_STATE *cs=0; diff --git a/include/my_dbug.h b/include/my_dbug.h index f08e94a1882..1ae9a50c76d 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -160,7 +160,8 @@ extern void _db_flush_(); #ifdef __WIN__ #define DBUG_SUICIDE() DBUG_ABORT() #else -#define DBUG_SUICIDE() (_db_flush_(), kill(getpid(), SIGKILL), pause()) +extern void _db_suicide_(); +#define DBUG_SUICIDE() (_db_flush_(), _db_suicide_()) #endif #else /* No debugger */ From cd36a6a5d552e86d47c52a17b59621f350518ee2 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 14 Dec 2010 12:33:03 +0300 Subject: [PATCH 091/110] Fixed following problems: --Bug#52157 various crashes and assertions with multi-table update, stored function --Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb --Bug#57703 create view cause Assertion failed: 0, file .\item_subselect.cc, line 846 --Bug#57352 valgrind warnings when creating view --Recently discovered problem when a nested materialized derived table is used before being populated and it leads to incorrect result We have several modes when we should disable subquery evaluation. The reasons for disabling are different. It could be uselessness of the evaluation as in case of 'CREATE VIEW' or 'PREPARE stmt', or we should disable subquery evaluation if tables are not locked yet as it happens in bug#54475, or too early evaluation of subqueries can lead to wrong result as it happened in Bug#19077. Main problem is that if subquery items are treated as const they are evaluated in ::fix_fields(), ::fix_length_and_dec() of the parental items as a lot of these methods have Item::val_...() calls inside. We have to make subqueries non-const to prevent unnecessary subquery evaluation. At the moment we have different methods for this. Here is a list of these modes: 1. PREPARE stmt; We use UNCACHEABLE_PREPARE flag. It is set during parsing in sql_parse.cc, mysql_new_select() for each SELECT_LEX object and cleared at the end of PREPARE in sql_prepare.cc, init_stmt_after_parse(). If this flag is set subquery becomes non-const and evaluation does not happen. 2. CREATE|ALTER VIEW, SHOW CREATE VIEW, I_S tables which process FRM files We use LEX::view_prepare_mode field. We set it before view preparation and check this flag in ::fix_fields(), ::fix_length_and_dec(). Some bugs are fixed using this approach, some are not(Bug#57352, Bug#57703). The problem here is that we have a lot of ::fix_fields(), ::fix_length_and_dec() where we use Item::val_...() calls for const items. 3. Derived tables with subquery = wrong result(Bug19077) The reason of this bug is too early subquery evaluation. It was fixed by adding Item::with_subselect field The check of this field in appropriate places prevents const item evaluation if the item have subquery. The fix for Bug19077 fixes only the problem with convert_constant_item() function and does not cover other places(::fix_fields(), ::fix_length_and_dec() again) where subqueries could be evaluated. Example: CREATE TABLE t1 (i INT, j BIGINT); INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2); SELECT * FROM (SELECT MIN(i) FROM t1 WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3; DROP TABLE t1; 4. Derived tables with subquery where subquery is evaluated before table locking(Bug#54475, Bug#52157) Suggested solution is following: -Introduce new field LEX::context_analysis_only with the following possible flags: #define CONTEXT_ANALYSIS_ONLY_PREPARE 1 #define CONTEXT_ANALYSIS_ONLY_VIEW 2 #define CONTEXT_ANALYSIS_ONLY_DERIVED 4 -Set/clean these flags when we perform context analysis operation -Item_subselect::const_item() returns result depending on LEX::context_analysis_only. If context_analysis_only is set then we return FALSE that means that subquery is non-const. As all subquery types are wrapped by Item_subselect it allow as to make subquery non-const when it's necessary. --- mysql-test/r/derived.result | 11 +++++++ mysql-test/r/multi_update.result | 11 +++++++ mysql-test/r/view.result | 13 ++++++++ .../suite/innodb/r/innodb_multi_update.result | 8 +++++ .../suite/innodb/t/innodb_multi_update.test | 11 +++++++ .../r/innodb_multi_update.result | 8 +++++ .../innodb_plugin/t/innodb_multi_update.test | 11 +++++++ mysql-test/t/derived.test | 11 +++++++ mysql-test/t/multi_update.test | 11 +++++++ mysql-test/t/view.test | 16 +++++++++ sql/item.cc | 11 +------ sql/item_cmpfunc.cc | 10 +++--- sql/item_func.cc | 2 +- sql/item_row.cc | 8 ++--- sql/item_subselect.cc | 20 +++-------- sql/item_subselect.h | 1 - sql/mysql_priv.h | 33 ++++++++++++++++--- sql/sql_class.h | 2 -- sql/sql_derived.cc | 3 +- sql/sql_lex.cc | 2 +- sql/sql_lex.h | 17 +++++----- sql/sql_parse.cc | 7 ---- sql/sql_prepare.cc | 18 ++-------- sql/sql_select.cc | 3 +- sql/sql_show.cc | 8 ++--- sql/sql_view.cc | 2 +- 26 files changed, 175 insertions(+), 83 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 80f04ffd455..61f1db9989f 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -400,4 +400,15 @@ SELECT 0 FROM (SELECT 0) t61; 0 0 +# +# A nested materialized derived table is used before being populated. +# (addon for bug#19077) +# +CREATE TABLE t1 (i INT, j BIGINT); +INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2); +SELECT * FROM (SELECT MIN(i) FROM t1 +WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3; +MIN(i) +1 +DROP TABLE t1; # End of 5.0 tests diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index d77ad1d2953..df3d7be6714 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -659,4 +659,15 @@ Error 1242 Subquery returns more than 1 row Error 1242 Subquery returns more than 1 row DROP TABLE t1, t2, t3; SET SESSION sql_safe_updates = DEFAULT; +# +# Bug#52157 various crashes and assertions with multi-table update, stored function +# +CREATE FUNCTION f1 () RETURNS BLOB RETURN 1; +CREATE TABLE t1 (f1 DATE); +INSERT INTO t1 VALUES('2001-01-01'); +UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1; +Warnings: +Warning 1292 Truncated incorrect datetime value: '1' +DROP FUNCTION f1; +DROP TABLE t1; end of tests diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 6dee239e21e..6b0a2103afa 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3884,6 +3884,19 @@ CREATE VIEW v1 AS SELECT 1 from t1 WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1')); DROP VIEW v1; DROP TABLE t1; +# +# Bug#57703 create view cause Assertion failed: 0, file .\item_subselect.cc, line 846 +# +CREATE TABLE t1(a int); +CREATE VIEW v1 AS SELECT 1 FROM t1 GROUP BY +SUBSTRING(1 FROM (SELECT 3 FROM t1 WHERE a >= ANY(SELECT 1))); +DROP VIEW v1; +DROP TABLE t1; +# +# Bug#57352 valgrind warnings when creating view +# +CREATE VIEW v1 AS SELECT 1 IN (1 LIKE 2,0) AS f; +DROP VIEW v1; # ----------------------------------------------------------------- # -- End of 5.1 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/suite/innodb/r/innodb_multi_update.result b/mysql-test/suite/innodb/r/innodb_multi_update.result index 7af9b030d1f..558fc3938a8 100644 --- a/mysql-test/suite/innodb/r/innodb_multi_update.result +++ b/mysql-test/suite/innodb/r/innodb_multi_update.result @@ -74,3 +74,11 @@ a b 4 14 5 15 drop table bug38999_1,bug38999_2; +# +# Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb +# +CREATE TABLE t1(f1 INT) ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; +ERROR 21000: Operand should contain 1 column(s) +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_multi_update.test b/mysql-test/suite/innodb/t/innodb_multi_update.test index 7ab17ccf70a..8356c20c88f 100644 --- a/mysql-test/suite/innodb/t/innodb_multi_update.test +++ b/mysql-test/suite/innodb/t/innodb_multi_update.test @@ -27,3 +27,14 @@ select * from bug38999_1; select * from bug38999_2; drop table bug38999_1,bug38999_2; + + +--echo # +--echo # Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb +--echo # +CREATE TABLE t1(f1 INT) ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +--error ER_OPERAND_COLUMNS +UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; +DROP TABLE t1; + diff --git a/mysql-test/suite/innodb_plugin/r/innodb_multi_update.result b/mysql-test/suite/innodb_plugin/r/innodb_multi_update.result index 7af9b030d1f..558fc3938a8 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_multi_update.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_multi_update.result @@ -74,3 +74,11 @@ a b 4 14 5 15 drop table bug38999_1,bug38999_2; +# +# Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb +# +CREATE TABLE t1(f1 INT) ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; +ERROR 21000: Operand should contain 1 column(s) +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test b/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test index 890889301e6..3d9a9a53193 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test @@ -27,3 +27,14 @@ select * from bug38999_1; select * from bug38999_2; drop table bug38999_1,bug38999_2; + + +--echo # +--echo # Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb +--echo # +CREATE TABLE t1(f1 INT) ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +--error ER_OPERAND_COLUMNS +UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; +DROP TABLE t1; + diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index d28c19bbd18..5ce6b52b74f 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -301,4 +301,15 @@ SELECT 0 FROM (SELECT 0) t56, (SELECT 0) t57, (SELECT 0) t58, (SELECT 0) t59, (SELECT 0) t60, (SELECT 0) t61; # 61 == MAX_TABLES +--echo # +--echo # A nested materialized derived table is used before being populated. +--echo # (addon for bug#19077) +--echo # + +CREATE TABLE t1 (i INT, j BIGINT); +INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2); +SELECT * FROM (SELECT MIN(i) FROM t1 +WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3; +DROP TABLE t1; + --echo # End of 5.0 tests diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 85d2ed19fda..5298701d790 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -673,4 +673,15 @@ SET t3.a = 0; DROP TABLE t1, t2, t3; SET SESSION sql_safe_updates = DEFAULT; +--echo # +--echo # Bug#52157 various crashes and assertions with multi-table update, stored function +--echo # + +CREATE FUNCTION f1 () RETURNS BLOB RETURN 1; +CREATE TABLE t1 (f1 DATE); +INSERT INTO t1 VALUES('2001-01-01'); +UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1; +DROP FUNCTION f1; +DROP TABLE t1; + --echo end of tests diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 3736f53b288..b1b3b5f2a83 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3925,6 +3925,22 @@ WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1')); DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # Bug#57703 create view cause Assertion failed: 0, file .\item_subselect.cc, line 846 +--echo # + +CREATE TABLE t1(a int); +CREATE VIEW v1 AS SELECT 1 FROM t1 GROUP BY +SUBSTRING(1 FROM (SELECT 3 FROM t1 WHERE a >= ANY(SELECT 1))); +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # Bug#57352 valgrind warnings when creating view +--echo # +CREATE VIEW v1 AS SELECT 1 IN (1 LIKE 2,0) AS f; +DROP VIEW v1; + --echo # ----------------------------------------------------------------- --echo # -- End of 5.1 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/item.cc b/sql/item.cc index d88a6e80bfe..c75db2dc15b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1712,16 +1712,7 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname, if (!(conv= (*arg)->safe_charset_converter(coll.collation)) && ((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII)) - { - /* - We should disable const subselect item evaluation because - subselect transformation does not happen in view_prepare_mode - and thus val_...() methods can not be called for const items. - */ - bool resolve_const= ((*arg)->type() == Item::SUBSELECT_ITEM && - thd->lex->view_prepare_mode) ? FALSE : TRUE; - conv= new Item_func_conv_charset(*arg, coll.collation, resolve_const); - } + conv= new Item_func_conv_charset(*arg, coll.collation, 1); if (!conv) { diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 6987dd9e053..e2faa51479c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -401,7 +401,7 @@ static bool convert_constant_item(THD *thd, Item_field *field_item, Field *field= field_item->field; int result= 0; - if (!(*item)->with_subselect && (*item)->const_item()) + if ((*item)->const_item()) { TABLE *table= field->table; ulong orig_sql_mode= thd->variables.sql_mode; @@ -497,7 +497,7 @@ void Item_bool_func2::fix_length_and_dec() } thd= current_thd; - if (!thd->is_context_analysis_only()) + if (!thd->lex->is_ps_or_view_context_analysis()) { if (args[0]->real_item()->type() == FIELD_ITEM) { @@ -801,7 +801,7 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value) confuse storage engines since in context analysis mode tables aren't locked. */ - if (!thd->is_context_analysis_only() && + if (!thd->lex->is_ps_or_view_context_analysis() && cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() && (str_arg->type() != Item::FUNC_ITEM || ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC)) @@ -1027,7 +1027,7 @@ Item** Arg_comparator::cache_converted_constant(THD *thd_arg, Item **value, Item_result type) { /* Don't need cache if doing context analysis only. */ - if (!thd_arg->is_context_analysis_only() && + if (!thd->lex->is_ps_or_view_context_analysis() && (*value)->const_item() && type != (*value)->result_type()) { Item_cache *cache= Item_cache::get_cache(*value, type); @@ -4686,7 +4686,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref) return TRUE; } - if (escape_item->const_item() && !thd->lex->view_prepare_mode) + if (escape_item->const_item()) { /* If we are on execution stage */ String *escape_str= escape_item->val_str(&cmp.value1); diff --git a/sql/item_func.cc b/sql/item_func.cc index b542969cfb0..2ba4415dbac 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6066,7 +6066,7 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) if (res) DBUG_RETURN(res); - if (thd->lex->view_prepare_mode) + if (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) { /* Here we check privileges of the stored routine only during view diff --git a/sql/item_row.cc b/sql/item_row.cc index 7535c1fa80b..408bc11eb9b 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -73,12 +73,8 @@ bool Item_row::fix_fields(THD *thd, Item **ref) used_tables_cache |= item->used_tables(); const_item_cache&= item->const_item() && !with_null; not_null_tables_cache|= item->not_null_tables(); - /* - Some subqueries transformations aren't done in the view_prepare_mode thus - is_null() will fail. So we skip is_null() calculation for CREATE VIEW as - not necessary. - */ - if (const_item_cache && !thd->lex->view_prepare_mode) + + if (const_item_cache) { if (item->cols() > 1) with_null|= item->null_inside(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index d521ad0b4e8..6f2286561b9 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -123,20 +123,6 @@ void Item_subselect::cleanup() } -/* - We cannot use generic Item::safe_charset_converter() because - Subselect transformation does not happen in view_prepare_mode - and thus we can not evaluate val_...() for const items. -*/ - -Item *Item_subselect::safe_charset_converter(CHARSET_INFO *tocs) -{ - Item_func_conv_charset *conv= - new Item_func_conv_charset(this, tocs, thd->lex->view_prepare_mode ? 0 : 1); - return conv->safe ? conv : NULL; -} - - void Item_singlerow_subselect::cleanup() { DBUG_ENTER("Item_singlerow_subselect::cleanup"); @@ -271,6 +257,7 @@ bool Item_subselect::exec() if (thd->is_error() || thd->killed) return 1; + DBUG_ASSERT(!thd->lex->context_analysis_only); /* Simulate a failure in sub-query execution. Used to test e.g. out of memory or query being killed conditions. @@ -307,7 +294,7 @@ table_map Item_subselect::used_tables() const bool Item_subselect::const_item() const { - return const_item_cache; + return thd->lex->context_analysis_only ? FALSE : const_item_cache; } Item *Item_subselect::get_tmp_table_item(THD *thd_arg) @@ -1638,7 +1625,8 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref) { bool result = 0; - if (thd_arg->lex->view_prepare_mode && left_expr && !left_expr->fixed) + if ((thd_arg->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) && + left_expr && !left_expr->fixed) result = left_expr->fix_fields(thd_arg, &left_expr); return result || Item_subselect::fix_fields(thd_arg, ref); diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 3806e68e377..467e9b22637 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -126,7 +126,6 @@ public: virtual void reset_value_registration() {} enum_parsing_place place() { return parsing_place; } bool walk(Item_processor processor, bool walk_subquery, uchar *arg); - Item *safe_charset_converter(CHARSET_INFO *tocs); /** Get the SELECT_LEX structure associated with this Item. diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 709a49b2036..04feb217d66 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -566,17 +566,42 @@ protected: #define MY_CHARSET_BIN_MB_MAXLEN 1 +/* + Flags below are set when we perform + context analysis of the statement and make + subqueries non-const. It prevents subquery + evaluation at context analysis stage. +*/ + +/* + Don't evaluate this subquery during statement prepare even if + it's a constant one. The flag is switched off in the end of + mysqld_stmt_prepare. +*/ +#define CONTEXT_ANALYSIS_ONLY_PREPARE 1 +/* + Special JOIN::prepare mode: changing of query is prohibited. + When creating a view, we need to just check its syntax omitting + any optimizations: afterwards definition of the view will be + reconstructed by means of ::print() methods and written to + to an .frm file. We need this definition to stay untouched. +*/ +#define CONTEXT_ANALYSIS_ONLY_VIEW 2 +/* + Don't evaluate this subquery during derived table prepare even if + it's a constant one. +*/ +#define CONTEXT_ANALYSIS_ONLY_DERIVED 4 + // uncachable cause #define UNCACHEABLE_DEPENDENT 1 #define UNCACHEABLE_RAND 2 #define UNCACHEABLE_SIDEEFFECT 4 /// forcing to save JOIN for explain #define UNCACHEABLE_EXPLAIN 8 -/** Don't evaluate subqueries in prepare even if they're not correlated */ -#define UNCACHEABLE_PREPARE 16 /* For uncorrelated SELECT in an UNION with some correlated SELECTs */ -#define UNCACHEABLE_UNITED 32 -#define UNCACHEABLE_CHECKOPTION 64 +#define UNCACHEABLE_UNITED 16 +#define UNCACHEABLE_CHECKOPTION 32 /* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */ #define UNDEF_POS (-1) diff --git a/sql/sql_class.h b/sql/sql_class.h index 774ae4abac4..cfb43356f2a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2180,8 +2180,6 @@ public: (variables.sql_mode & MODE_STRICT_ALL_TABLES))); } void set_status_var_init(); - bool is_context_analysis_only() - { return stmt_arena->is_stmt_prepare() || lex->view_prepare_mode; } void reset_n_backup_open_tables_state(Open_tables_state *backup); void restore_backup_open_tables_state(Open_tables_state *backup); void reset_sub_statement_state(Sub_statement_state *backup, uint new_state); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 782589f7d0f..3214c756bc7 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -147,10 +147,11 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list) if (!(derived_result= new select_union)) DBUG_RETURN(TRUE); // out of memory + lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED; // st_select_lex_unit::prepare correctly work for single select if ((res= unit->prepare(thd, derived_result, 0))) goto exit; - + lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED; if ((res= check_duplicate_names(unit->types, 0))) goto exit; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 24c51be2512..9ea144df9bc 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -305,7 +305,7 @@ void lex_start(THD *thd) lex->select_lex.group_list.empty(); lex->describe= 0; lex->subqueries= FALSE; - lex->view_prepare_mode= FALSE; + lex->context_analysis_only= 0; lex->derived_tables= 0; lex->lock_option= TL_READ; lex->safe_to_cache_query= 1; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 9131cec9d04..b1f30b07824 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1715,14 +1715,8 @@ typedef struct st_lex : public Query_tables_list bool verbose, no_write_to_binlog; bool tx_chain, tx_release; - /* - Special JOIN::prepare mode: changing of query is prohibited. - When creating a view, we need to just check its syntax omitting - any optimizations: afterwards definition of the view will be - reconstructed by means of ::print() methods and written to - to an .frm file. We need this definition to stay untouched. - */ - bool view_prepare_mode; + + uint8 context_analysis_only; bool safe_to_cache_query; bool subqueries, ignore; st_parsing_options parsing_options; @@ -1843,6 +1837,13 @@ typedef struct st_lex : public Query_tables_list delete_dynamic(&plugins); } + inline bool is_ps_or_view_context_analysis() + { + return (context_analysis_only & + (CONTEXT_ANALYSIS_ONLY_PREPARE | + CONTEXT_ANALYSIS_ONLY_VIEW)); + } + inline void uncacheable(uint8 cause) { safe_to_cache_query= 0; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7cf64134d70..abfc2ec26b3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5865,13 +5865,6 @@ mysql_new_select(LEX *lex, bool move_down) DBUG_RETURN(1); } select_lex->nest_level= lex->nest_level; - /* - Don't evaluate this subquery during statement prepare even if - it's a constant one. The flag is switched off in the end of - mysqld_stmt_prepare. - */ - if (thd->stmt_arena->is_stmt_prepare()) - select_lex->uncacheable|= UNCACHEABLE_PREPARE; if (move_down) { SELECT_LEX_UNIT *unit; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 5ba375f9710..aadfb831087 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1688,7 +1688,7 @@ static bool mysql_test_create_view(Prepared_statement *stmt) if (open_normal_and_derived_tables(thd, tables, 0)) goto err; - lex->view_prepare_mode= 1; + lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; res= select_like_stmt_test(stmt, 0, 0); err: @@ -2234,19 +2234,6 @@ end: } -/** Init PS/SP specific parse tree members. */ - -static void init_stmt_after_parse(LEX *lex) -{ - SELECT_LEX *sl= lex->all_selects_list; - /* - Switch off a temporary flag that prevents evaluation of - subqueries in statement prepare. - */ - for (; sl; sl= sl->next_select_in_list()) - sl->uncacheable&= ~UNCACHEABLE_PREPARE; -} - /** SQLCOM_PREPARE implementation. @@ -3080,6 +3067,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) parser_state.m_lip.stmt_prepare_mode= TRUE; lex_start(thd); + lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_PREPARE; error= parse_sql(thd, & parser_state, NULL) || thd->is_error() || @@ -3132,7 +3120,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) if (error == 0) { setup_set_params(); - init_stmt_after_parse(lex); + lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE; state= Query_arena::PREPARED; flags&= ~ (uint) IS_IN_USE; /* diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c17cb946fa3..5bb5650fae7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -538,7 +538,8 @@ JOIN::prepare(Item ***rref_pointer_array, thd->lex->allow_sum_func= save_allow_sum_func; } - if (!thd->lex->view_prepare_mode && !(select_options & SELECT_DESCRIBE)) + if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) && + !(select_options & SELECT_DESCRIBE)) { Item_subselect *subselect; /* Is it subselect? */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ee0e2bf5ce7..ed7a8d32eb8 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -718,7 +718,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) table_list->table_name)); /* We want to preserve the tree for views. */ - thd->lex->view_prepare_mode= TRUE; + thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; { Show_create_error_handler view_error_suppressor(thd, table_list); @@ -3315,7 +3315,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) uint derived_tables= lex->derived_tables; int error= 1; Open_tables_state open_tables_state_backup; - bool save_view_prepare_mode= lex->view_prepare_mode; + uint8 save_context_analysis_only= lex->context_analysis_only; Query_tables_list query_tables_list_backup; #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *sctx= thd->security_ctx; @@ -3323,7 +3323,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) uint table_open_method; DBUG_ENTER("get_all_tables"); - lex->view_prepare_mode= TRUE; + lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; lex->reset_n_backup_query_tables_list(&query_tables_list_backup); /* @@ -3540,7 +3540,7 @@ err: lex->restore_backup_query_tables_list(&query_tables_list_backup); lex->derived_tables= derived_tables; lex->all_selects_list= old_all_select_lex; - lex->view_prepare_mode= save_view_prepare_mode; + lex->context_analysis_only= save_context_analysis_only; lex->sql_command= save_sql_command; DBUG_RETURN(error); } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 133574089aa..6cb4f590ae0 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -545,7 +545,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } /* prepare select to resolve all fields */ - lex->view_prepare_mode= 1; + lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; if (unit->prepare(thd, 0, 0)) { /* From cd27e25dc01a03d6f8578419ccae34c87d63377b Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 14 Dec 2010 12:13:35 +0100 Subject: [PATCH 092/110] Bug#45717: A few test cases are disabled due to closed Bug#30577 Backport from 5.5. OK from Anitha G. to push to 5.1. Removed floor(float_col) tests, enabled floor(decimal_col) tests --- .../inc/part_supported_sql_funcs_main.inc | 23 ---- .../suite/parts/inc/partition_decimal.inc | 9 +- .../suite/parts/inc/partition_double.inc | 51 --------- .../suite/parts/inc/partition_float.inc | 50 -------- .../parts/r/partition_decimal_innodb.result | 108 ++++++++++++++++++ .../parts/r/partition_decimal_myisam.result | 108 ++++++++++++++++++ 6 files changed, 218 insertions(+), 131 deletions(-) diff --git a/mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc b/mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc index 25a9774d2a1..45d77225a23 100644 --- a/mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc +++ b/mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc @@ -39,29 +39,6 @@ let $val3 = 17 ; let $val4 = 15 ; --source suite/parts/inc/partition_supported_sql_funcs.inc - -let $sqlfunc = ceiling(col1); -let $valsqlfunc = ceiling(15); -let $coltype = float(7,4); -let $infile = part_supported_sql_funcs_int_float.inc; -let $val1 = 5.1230; -let $val2 = 13.345; -let $val3 = 17.987; -let $val4 = 15.654 ; -# DISABLED due to bug 30577 -#--source suite/parts/inc/partition_supported_sql_funcs.inc - -let $sqlfunc = floor(col1); -let $valsqlfunc = floor(15.123); -let $coltype = float(7,4); -let $infile = part_supported_sql_funcs_int_float.inc; -let $val1 = 5.1230; -let $val2 = 13.345; -let $val3 = 17.987; -let $val4 = 15.654 ; -# DISABLED due to bug 30577 -#--source suite/parts/inc/partition_supported_sql_funcs.inc - let $sqlfunc = mod(col1,10); let $valsqlfunc = mod(15,10); let $coltype = int; diff --git a/mysql-test/suite/parts/inc/partition_decimal.inc b/mysql-test/suite/parts/inc/partition_decimal.inc index 17cef08e275..7d3fe058de9 100644 --- a/mysql-test/suite/parts/inc/partition_decimal.inc +++ b/mysql-test/suite/parts/inc/partition_decimal.inc @@ -37,10 +37,8 @@ drop table t2; # Bug 30577: FLOOR() and CEILING() not usable as partition functions # Partition functions are required to return INT_RESULT; FLOOR() and -# CEILING() do not, unless they have an INT argument. Disable this -# portion of the test until bug 30577 is fixed. +# CEILING() do not, unless they have an INT or DECIMAL argument. ---disable_parsing eval create table t3 (a decimal(18,9) not null, primary key(a)) engine=$engine partition by range (floor(a)) subpartition by key (a) subpartitions 2 ( @@ -65,7 +63,7 @@ select count(*) from t3; drop table t3; eval create table t4 (a decimal(18,9) not null, primary key(a)) engine=$engine -partition by list (floor(a)) subpartition by key (a) subpartitions 2 ( +partition by list (ceiling(a)) subpartition by key (a) subpartitions 2 ( partition pa2 values in (1,2), partition pa4 values in (3,4), partition pa6 values in (5,6), @@ -85,6 +83,3 @@ dec $count; --enable_query_log select count(*) from t4; drop table t4; - -# Disabled due to Bug 30577 ---enable_parsing diff --git a/mysql-test/suite/parts/inc/partition_double.inc b/mysql-test/suite/parts/inc/partition_double.inc index befbe860b86..cfae95022ce 100644 --- a/mysql-test/suite/parts/inc/partition_double.inc +++ b/mysql-test/suite/parts/inc/partition_double.inc @@ -34,54 +34,3 @@ dec $count; --enable_query_log select count(*) from t2; drop table t2; - - -# Bug 30577: FLOOR() and CEILING() not usable as partition functions -# Partition functions are required to return INT_RESULT; FLOOR() and -# CEILING() do not, unless they have an INT argument. Disable this -# portion of the test until bug 30577 is fixed. - ---disable_parsing - -eval create table t3 (a double not null, primary key(a)) engine=$engine -partition by range (floor(a)) subpartition by key (a) subpartitions 3 ( -partition pa1 values less than (3), -partition pa3 values less than (6), -partition pa10 values less than (10) -); -show create table t3; -let $count=9; ---echo $count*3 inserts; -while ($count) -{ -eval insert into t3 values ($count); -eval insert into t3 values ($count+0.33); -eval insert into t3 values ($count+0.75); -dec $count; -} -select count(*) from t3; -select * from t3; -drop table t3; - -eval create table t4 (a double not null, primary key(a)) engine=$engine -partition by list (floor(a)) subpartition by key (a) subpartitions 3 ( -partition pa1 values in (1,2,3), -partition pa3 values in (4,5,6), -partition pa10 values in (7,8,9,10) -); -show create table t4; -let $count=9; ---echo $count*3 inserts; -while ($count) -{ -eval insert into t4 values ($count); -eval insert into t4 values ($count+0.33); -eval insert into t4 values ($count+0.75); -dec $count; -} -select count(*) from t4; -select * from t4; -drop table t4; - -# Disabled due to Bug 30577 ---enable_parsing diff --git a/mysql-test/suite/parts/inc/partition_float.inc b/mysql-test/suite/parts/inc/partition_float.inc index 34f14137d4d..7fa6b3043be 100644 --- a/mysql-test/suite/parts/inc/partition_float.inc +++ b/mysql-test/suite/parts/inc/partition_float.inc @@ -38,53 +38,3 @@ dec $count; --enable_query_log select count(*) from t2; drop table t2; - -# Bug 30577: FLOOR() and CEILING() not usable as partition functions -# Partition functions are required to return INT_RESULT; FLOOR() and -# CEILING() do not, unless they have an INT argument. Disable this -# portion of the test until bug 30577 is fixed. - ---disable_parsing - -eval create table t3 (a float not null, primary key(a)) engine=$engine -partition by range (floor(a)) subpartition by key (a) subpartitions 3 ( -partition pa1 values less than (3), -partition pa3 values less than (6), -partition pa10 values less than (10) -); -show create table t3; -let $count=9; ---echo $count*3 inserts; -while ($count) -{ -eval insert into t3 values ($count); -eval insert into t3 values ($count+0.33); -eval insert into t3 values ($count+0.75); -dec $count; -} -select count(*) from t3; -select * from t3; -drop table t3; - -eval create table t4 (a float not null, primary key(a)) engine=$engine -partition by list (floor(a)) subpartition by key (a) subpartitions 3 ( -partition pa1 values in (1,2,3), -partition pa3 values in (4,5,6), -partition pa10 values in (7,8,9,10) -); -show create table t4; -let $count=9; ---echo $count*3 inserts; -while ($count) -{ -eval insert into t4 values ($count); -eval insert into t4 values ($count+0.33); -eval insert into t4 values ($count+0.75); -dec $count; -} -select count(*) from t4; -select * from t4; -drop table t4; - -# Disabled due to Bug 30577 ---enable_parsing diff --git a/mysql-test/suite/parts/r/partition_decimal_innodb.result b/mysql-test/suite/parts/r/partition_decimal_innodb.result index 70debf3c595..c69c880cc6f 100644 --- a/mysql-test/suite/parts/r/partition_decimal_innodb.result +++ b/mysql-test/suite/parts/r/partition_decimal_innodb.result @@ -86,3 +86,111 @@ select count(*) from t2; count(*) 3072 drop table t2; +create table t3 (a decimal(18,9) not null, primary key(a)) engine='InnoDB' +partition by range (floor(a)) subpartition by key (a) subpartitions 2 ( +partition pa2 values less than (2), +partition pa4 values less than (4), +partition pa6 values less than (6), +partition pa8 values less than (8), +partition pa10 values less than (10) +); +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` decimal(18,9) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY RANGE (floor(a)) +SUBPARTITION BY KEY (a) +SUBPARTITIONS 2 +(PARTITION pa2 VALUES LESS THAN (2) ENGINE = InnoDB, + PARTITION pa4 VALUES LESS THAN (4) ENGINE = InnoDB, + PARTITION pa6 VALUES LESS THAN (6) ENGINE = InnoDB, + PARTITION pa8 VALUES LESS THAN (8) ENGINE = InnoDB, + PARTITION pa10 VALUES LESS THAN (10) ENGINE = InnoDB) */ +9*3 inserts; +insert into t3 values (9); +insert into t3 values (9+0.333333333); +insert into t3 values (9+0.755555555); +insert into t3 values (8); +insert into t3 values (8+0.333333333); +insert into t3 values (8+0.755555555); +insert into t3 values (7); +insert into t3 values (7+0.333333333); +insert into t3 values (7+0.755555555); +insert into t3 values (6); +insert into t3 values (6+0.333333333); +insert into t3 values (6+0.755555555); +insert into t3 values (5); +insert into t3 values (5+0.333333333); +insert into t3 values (5+0.755555555); +insert into t3 values (4); +insert into t3 values (4+0.333333333); +insert into t3 values (4+0.755555555); +insert into t3 values (3); +insert into t3 values (3+0.333333333); +insert into t3 values (3+0.755555555); +insert into t3 values (2); +insert into t3 values (2+0.333333333); +insert into t3 values (2+0.755555555); +insert into t3 values (1); +insert into t3 values (1+0.333333333); +insert into t3 values (1+0.755555555); +select count(*) from t3; +count(*) +27 +drop table t3; +create table t4 (a decimal(18,9) not null, primary key(a)) engine='InnoDB' +partition by list (ceiling(a)) subpartition by key (a) subpartitions 2 ( +partition pa2 values in (1,2), +partition pa4 values in (3,4), +partition pa6 values in (5,6), +partition pa8 values in (7,8), +partition pa10 values in (9,10) +); +show create table t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `a` decimal(18,9) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (ceiling(a)) +SUBPARTITION BY KEY (a) +SUBPARTITIONS 2 +(PARTITION pa2 VALUES IN (1,2) ENGINE = InnoDB, + PARTITION pa4 VALUES IN (3,4) ENGINE = InnoDB, + PARTITION pa6 VALUES IN (5,6) ENGINE = InnoDB, + PARTITION pa8 VALUES IN (7,8) ENGINE = InnoDB, + PARTITION pa10 VALUES IN (9,10) ENGINE = InnoDB) */ +9*3 inserts; +insert into t4 values (9); +insert into t4 values (9+0.333333333); +insert into t4 values (9+0.755555555); +insert into t4 values (8); +insert into t4 values (8+0.333333333); +insert into t4 values (8+0.755555555); +insert into t4 values (7); +insert into t4 values (7+0.333333333); +insert into t4 values (7+0.755555555); +insert into t4 values (6); +insert into t4 values (6+0.333333333); +insert into t4 values (6+0.755555555); +insert into t4 values (5); +insert into t4 values (5+0.333333333); +insert into t4 values (5+0.755555555); +insert into t4 values (4); +insert into t4 values (4+0.333333333); +insert into t4 values (4+0.755555555); +insert into t4 values (3); +insert into t4 values (3+0.333333333); +insert into t4 values (3+0.755555555); +insert into t4 values (2); +insert into t4 values (2+0.333333333); +insert into t4 values (2+0.755555555); +insert into t4 values (1); +insert into t4 values (1+0.333333333); +insert into t4 values (1+0.755555555); +select count(*) from t4; +count(*) +27 +drop table t4; diff --git a/mysql-test/suite/parts/r/partition_decimal_myisam.result b/mysql-test/suite/parts/r/partition_decimal_myisam.result index f9f7a1e4fe2..cdafb721ea4 100644 --- a/mysql-test/suite/parts/r/partition_decimal_myisam.result +++ b/mysql-test/suite/parts/r/partition_decimal_myisam.result @@ -86,3 +86,111 @@ select count(*) from t2; count(*) 196605 drop table t2; +create table t3 (a decimal(18,9) not null, primary key(a)) engine='MYISAM' +partition by range (floor(a)) subpartition by key (a) subpartitions 2 ( +partition pa2 values less than (2), +partition pa4 values less than (4), +partition pa6 values less than (6), +partition pa8 values less than (8), +partition pa10 values less than (10) +); +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` decimal(18,9) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY RANGE (floor(a)) +SUBPARTITION BY KEY (a) +SUBPARTITIONS 2 +(PARTITION pa2 VALUES LESS THAN (2) ENGINE = MyISAM, + PARTITION pa4 VALUES LESS THAN (4) ENGINE = MyISAM, + PARTITION pa6 VALUES LESS THAN (6) ENGINE = MyISAM, + PARTITION pa8 VALUES LESS THAN (8) ENGINE = MyISAM, + PARTITION pa10 VALUES LESS THAN (10) ENGINE = MyISAM) */ +9*3 inserts; +insert into t3 values (9); +insert into t3 values (9+0.333333333); +insert into t3 values (9+0.755555555); +insert into t3 values (8); +insert into t3 values (8+0.333333333); +insert into t3 values (8+0.755555555); +insert into t3 values (7); +insert into t3 values (7+0.333333333); +insert into t3 values (7+0.755555555); +insert into t3 values (6); +insert into t3 values (6+0.333333333); +insert into t3 values (6+0.755555555); +insert into t3 values (5); +insert into t3 values (5+0.333333333); +insert into t3 values (5+0.755555555); +insert into t3 values (4); +insert into t3 values (4+0.333333333); +insert into t3 values (4+0.755555555); +insert into t3 values (3); +insert into t3 values (3+0.333333333); +insert into t3 values (3+0.755555555); +insert into t3 values (2); +insert into t3 values (2+0.333333333); +insert into t3 values (2+0.755555555); +insert into t3 values (1); +insert into t3 values (1+0.333333333); +insert into t3 values (1+0.755555555); +select count(*) from t3; +count(*) +27 +drop table t3; +create table t4 (a decimal(18,9) not null, primary key(a)) engine='MYISAM' +partition by list (ceiling(a)) subpartition by key (a) subpartitions 2 ( +partition pa2 values in (1,2), +partition pa4 values in (3,4), +partition pa6 values in (5,6), +partition pa8 values in (7,8), +partition pa10 values in (9,10) +); +show create table t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `a` decimal(18,9) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (ceiling(a)) +SUBPARTITION BY KEY (a) +SUBPARTITIONS 2 +(PARTITION pa2 VALUES IN (1,2) ENGINE = MyISAM, + PARTITION pa4 VALUES IN (3,4) ENGINE = MyISAM, + PARTITION pa6 VALUES IN (5,6) ENGINE = MyISAM, + PARTITION pa8 VALUES IN (7,8) ENGINE = MyISAM, + PARTITION pa10 VALUES IN (9,10) ENGINE = MyISAM) */ +9*3 inserts; +insert into t4 values (9); +insert into t4 values (9+0.333333333); +insert into t4 values (9+0.755555555); +insert into t4 values (8); +insert into t4 values (8+0.333333333); +insert into t4 values (8+0.755555555); +insert into t4 values (7); +insert into t4 values (7+0.333333333); +insert into t4 values (7+0.755555555); +insert into t4 values (6); +insert into t4 values (6+0.333333333); +insert into t4 values (6+0.755555555); +insert into t4 values (5); +insert into t4 values (5+0.333333333); +insert into t4 values (5+0.755555555); +insert into t4 values (4); +insert into t4 values (4+0.333333333); +insert into t4 values (4+0.755555555); +insert into t4 values (3); +insert into t4 values (3+0.333333333); +insert into t4 values (3+0.755555555); +insert into t4 values (2); +insert into t4 values (2+0.333333333); +insert into t4 values (2+0.755555555); +insert into t4 values (1); +insert into t4 values (1+0.333333333); +insert into t4 values (1+0.755555555); +select count(*) from t4; +count(*) +27 +drop table t4; From 622ae4184cb3e691bbb3346f0d9079a45799bbce Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 14 Dec 2010 19:08:25 +0300 Subject: [PATCH 093/110] Bug#57818 string conversion function died Bug#57913 large negative number to string conversion functions crash String object which is used as result container of the item has uninitialized 'str_charset' field. This object might be used later to preform some internal operations and str_charset field is involved in these operations. It leads to crash. The fix is to intialize str_charset in my_decimal2string() func. --- mysql-test/r/func_str.result | 12 ++++++++++++ mysql-test/t/func_str.test | 7 +++++++ sql/my_decimal.cc | 1 + 3 files changed, 20 insertions(+) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 4268268fabb..0321b2d85ad 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2600,4 +2600,16 @@ ORDER BY QUOTE(t1.a); 1 1 DROP TABLE t1; +# +# Bug#57913 large negative number to string conversion functions crash +# Bug#57810 case/when/then : Assertion failed: length || !scale +# +SELECT '1' IN ('1', SUBSTRING(-9223372036854775809, 1)); +'1' IN ('1', SUBSTRING(-9223372036854775809, 1)) +1 +SELECT CONVERT(('' IN (REVERSE(CAST(('') AS DECIMAL)), '')), CHAR(3)); +CONVERT(('' IN (REVERSE(CAST(('') AS DECIMAL)), '')), CHAR(3)) +1 +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: '' End of 5.1 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 3392a41519b..fdcfbcf519e 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1362,4 +1362,11 @@ SELECT 1 FROM t1, t1 t2 ORDER BY QUOTE(t1.a); DROP TABLE t1; +--echo # +--echo # Bug#57913 large negative number to string conversion functions crash +--echo # Bug#57810 case/when/then : Assertion failed: length || !scale +--echo # +SELECT '1' IN ('1', SUBSTRING(-9223372036854775809, 1)); +SELECT CONVERT(('' IN (REVERSE(CAST(('') AS DECIMAL)), '')), CHAR(3)); + --echo End of 5.1 tests diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 3aa01880b83..26377bc1562 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -109,6 +109,7 @@ int my_decimal2string(uint mask, const my_decimal *d, result= decimal2string((decimal_t*) d, (char*) str->ptr(), &length, (int)fixed_prec, fixed_dec, filler); + str->set_charset(&my_charset_bin); str->length(length); return check_result(mask, result); } From 1d0eae6fca07bf30f5f4d0e84d50dac9f2b0ef53 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 14 Dec 2010 16:43:25 +0000 Subject: [PATCH 094/110] BUG 46697 Addressing review comments. --- mysql-test/suite/rpl/r/rpl_stm_EE_err2.result | 2 +- sql/log_event.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_stm_EE_err2.result b/mysql-test/suite/rpl/r/rpl_stm_EE_err2.result index da24c4f5db1..4bbbc0e99c6 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_EE_err2.result +++ b/mysql-test/suite/rpl/r/rpl_stm_EE_err2.result @@ -11,6 +11,6 @@ set sql_log_bin=1; insert into t1 values(1),(2); ERROR 23000: Duplicate entry '2' for key 'a' drop table t1; -Error: "Query caused different errors on master and slave. Error on master: message format='Duplicate entry '%-.192s' for key %d' error code=1062 ; Error on slave: actual message='no error', error code=0. Default database: 'test'. Query: 'insert into t1 values(1),(2)'" (expected different error codes on master and slave) +Error: "Query caused different errors on master and slave. Error on master: message (format)='Duplicate entry '%-.192s' for key %d' error code=1062 ; Error on slave: actual message='no error', error code=0. Default database: 'test'. Query: 'insert into t1 values(1),(2)'" (expected different error codes on master and slave) Errno: "0" (expected 0) drop table t1; diff --git a/sql/log_event.cc b/sql/log_event.cc index b4599b8fd8c..d3d95c5b18f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3337,7 +3337,7 @@ compare_errors: rli->report(ERROR_LEVEL, 0, "\ Query caused different errors on master and slave. \ -Error on master: message format='%s' error code=%d ; \ +Error on master: message (format)='%s' error code=%d ; \ Error on slave: actual message='%s', error code=%d. \ Default database: '%s'. Query: '%s'", ER_SAFE(expected_error), From 01521a0afbacd764dd4632486ce340f4aa68c780 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Tue, 14 Dec 2010 23:52:53 +0300 Subject: [PATCH 095/110] backport of bug #54476 fix from 5.1-bugteam to 5.0-bugteam. Original revid: alexey.kopytov@sun.com-20100723115254-jjwmhq97b9wl932l > Bug #54476: crash when group_concat and 'with rollup' in > prepared statements > > Using GROUP_CONCAT() together with the WITH ROLLUP modifier > could crash the server. > > The reason was a combination of several facts: > > 1. The Item_func_group_concat class stores pointers to ORDER > objects representing the columns in the ORDER BY clause of > GROUP_CONCAT(). > > 2. find_order_in_list() called from > Item_func_group_concat::setup() modifies the ORDER objects so > that their 'item' member points to the arguments list > allocated in the Item_func_group_concat constructor. > > 3. In some cases (e.g. in JOIN::rollup_make_fields) a copy of > the original Item_func_group_concat object could be created by > using the Item_func_group_concat::Item_func_group_concat(THD > *thd, Item_func_group_concat *item) copy constructor. The > latter essentially creates a shallow copy of the source > object. Memory for the arguments array is allocated on > thd->mem_root, but the pointers for arguments and ORDER are > copied verbatim. > > What happens in the test case is that when executing the query > for the first time, after a copy of the original > Item_func_group_concat object has been created by > JOIN::rollup_make_fields(), find_order_in_list() is called for > this new object. It then resolves ORDER BY by modifying the > ORDER objects so that they point to elements of the arguments > array which is local to the cloned object. When thd->mem_root > is freed upon completing the execution, pointers in the ORDER > objects become invalid. Those ORDER objects, however, are also > shared with the original Item_func_group_concat object which is > preserved between executions of a prepared statement. So the > first call to find_order_in_list() for the original object on > the second execution tries to dereference an invalid pointer. > > The solution is to create copies of the ORDER objects when > copying Item_func_group_concat to not leave any stale pointers > in other instances with different lifecycles. --- mysql-test/r/func_gconcat.result | 18 ++++++++++++++++++ mysql-test/t/func_gconcat.test | 14 ++++++++++++++ sql/item_sum.cc | 19 ++++++++++++++++++- sql/table.h | 1 - 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index d69a340cddb..ca09a3285ec 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -989,4 +989,22 @@ SELECT 1 FROM 1 1 DROP TABLE t1; +# +# Bug #54476: crash when group_concat and 'with rollup' in prepared statements +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1), (2); +PREPARE stmt FROM "SELECT GROUP_CONCAT(t1.a ORDER BY t1.a) FROM t1 JOIN t1 t2 GROUP BY t1.a WITH ROLLUP"; +EXECUTE stmt; +GROUP_CONCAT(t1.a ORDER BY t1.a) +1,1 +2,2 +1,1,2,2 +EXECUTE stmt; +GROUP_CONCAT(t1.a ORDER BY t1.a) +1,1 +2,2 +1,1,2,2 +DEALLOCATE PREPARE stmt; +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 1cbf045e95d..ee9ddf1f1a9 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -708,4 +708,18 @@ SELECT 1 FROM DROP TABLE t1; +--echo # +--echo # Bug #54476: crash when group_concat and 'with rollup' in prepared statements +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1), (2); + +PREPARE stmt FROM "SELECT GROUP_CONCAT(t1.a ORDER BY t1.a) FROM t1 JOIN t1 t2 GROUP BY t1.a WITH ROLLUP"; +EXECUTE stmt; +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 4c2bde90100..244ea4c34b6 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3170,7 +3170,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, tree(item->tree), unique_filter(item->unique_filter), table(item->table), - order(item->order), context(item->context), arg_count_order(item->arg_count_order), arg_count_field(item->arg_count_field), @@ -3183,6 +3182,24 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, { quick_group= item->quick_group; result.set_charset(collation.collation); + + /* + Since the ORDER structures pointed to by the elements of the 'order' array + may be modified in find_order_in_list() called from + Item_func_group_concat::setup(), create a copy of those structures so that + such modifications done in this object would not have any effect on the + object being copied. + */ + ORDER *tmp; + if (!(order= (ORDER **) thd->alloc(sizeof(ORDER *) * arg_count_order + + sizeof(ORDER) * arg_count_order))) + return; + tmp= (ORDER *)(order + arg_count_order); + for (uint i= 0; i < arg_count_order; i++, tmp++) + { + memcpy(tmp, item->order[i], sizeof(ORDER)); + order[i]= tmp; + } } diff --git a/sql/table.h b/sql/table.h index f162c2ed8ca..0a89db8bbff 100644 --- a/sql/table.h +++ b/sql/table.h @@ -31,7 +31,6 @@ typedef struct st_order { struct st_order *next; Item **item; /* Point at item in select fields */ Item *item_ptr; /* Storage for initial item */ - Item **item_copy; /* For SPs; the original item ptr */ int counter; /* position in SELECT list, correct only if counter_used is true*/ bool asc; /* true if ascending */ From 7f0236de48902e1cf4f628f73cf20c18884c02d9 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 15 Dec 2010 12:58:37 +0300 Subject: [PATCH 096/110] Bug#58321 No warning when characters outside BMP0 is converted to UCS2 Problem: when inserting supplementary characters to an UCS2 column, character was silently shrinked to 16-bit value. Fix: produce a warning on attempt to insert a supplementary character, and convert to question mark. @ mysql-test/r/ctype_many.result @ mysql-test/t/ctype_many.test Adding tests @ strings/ctype-ucs2.c Check if wc is greater than the highest value supported (0xFFFF), return MY_CS_ILUNI if true. --- mysql-test/r/ctype_many.result | 22 ++++++++++++++++++++++ mysql-test/t/ctype_many.test | 20 ++++++++++++++++++++ strings/ctype-ucs2.c | 5 ++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ctype_many.result b/mysql-test/r/ctype_many.result index 4730b4df668..0b061f507a7 100644 --- a/mysql-test/r/ctype_many.result +++ b/mysql-test/r/ctype_many.result @@ -1684,6 +1684,9 @@ ARMENIAN CAPIT ECH 2 ARMENIAN CAPIT ZA 2 DROP TABLE t1; # +# Start of 5.5 tests +# +# # WL#1213 Implement 4-byte UTF8, UTF16 and UTF32 # Testing that only utf8mb4 is superset for utf8 # No other Unicode character set pairs have superset/subset relations @@ -1739,3 +1742,22 @@ ERROR HY000: Illegal mix of collations (utf32_general_ci,IMPLICIT) and (utf8mb4_ SELECT CHARSET(CONCAT(utf32, utf16)) FROM t1; ERROR HY000: Illegal mix of collations (utf32_general_ci,IMPLICIT) and (utf16_general_ci,IMPLICIT) for operation 'concat' DROP TABLE t1; +# +# Bug#58321 No warning when characters outside BMP0 is converted to UCS2 +# +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf32); +CREATE TABLE t2 (a VARCHAR(10) CHARACTER SET ucs2); +INSERT INTO t1 VALUES (0x10082), (0x12345); +INSERT INTO t2 SELECT * FROM t1; +Warnings: +Warning 1366 Incorrect string value: '\x00\x01\x00\x82' for column 'a' at row 1 +Warning 1366 Incorrect string value: '\x00\x01\x23\x45' for column 'a' at row 2 +SELECT HEX(a) FROM t2; +HEX(a) +003F +003F +DROP TABLE t1; +DROP TABLE t2; +# +# End of 5.5 tests +# diff --git a/mysql-test/t/ctype_many.test b/mysql-test/t/ctype_many.test index 67726c53585..5aa1f6e7c7d 100644 --- a/mysql-test/t/ctype_many.test +++ b/mysql-test/t/ctype_many.test @@ -216,6 +216,10 @@ DROP TABLE t1; # End of 4.1 tests +--echo # +--echo # Start of 5.5 tests +--echo # + --echo # --echo # WL#1213 Implement 4-byte UTF8, UTF16 and UTF32 --echo # Testing that only utf8mb4 is superset for utf8 @@ -284,3 +288,19 @@ SELECT CHARSET(CONCAT(utf32, utf8mb4)) FROM t1; SELECT CHARSET(CONCAT(utf32, utf16)) FROM t1; DROP TABLE t1; + +--echo # +--echo # Bug#58321 No warning when characters outside BMP0 is converted to UCS2 +--echo # +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf32); +CREATE TABLE t2 (a VARCHAR(10) CHARACTER SET ucs2); +INSERT INTO t1 VALUES (0x10082), (0x12345); +INSERT INTO t2 SELECT * FROM t1; +SELECT HEX(a) FROM t2; +DROP TABLE t1; +DROP TABLE t2; + + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index d9f546d435e..1eb4b8de7ed 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -2693,7 +2693,10 @@ static int my_uni_ucs2(CHARSET_INFO *cs __attribute__((unused)) , { if ( r+2 > e ) return MY_CS_TOOSMALL2; - + + if (wc > 0xFFFF) /* UCS2 does not support characters outside BMP */ + return MY_CS_ILUNI; + r[0]= (uchar) (wc >> 8); r[1]= (uchar) (wc & 0xFF); return 2; From 40d32fc8c142745c636642f5e48011afa023aa48 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 15 Dec 2010 18:00:54 -0200 Subject: [PATCH 097/110] Cleanup my_win_init by moving time and registry related initialization to specific functions. Also, remove a large block of white space. There shouldn't be any functional change. --- mysys/my_init.c | 194 +++++++++++++++++++++++------------------------- 1 file changed, 91 insertions(+), 103 deletions(-) diff --git a/mysys/my_init.c b/mysys/my_init.c index e3b189c27bb..ab6ffef7ac7 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -311,6 +311,89 @@ int handle_rtc_failure(int err_type, const char *file, int line, #pragma runtime_checks("", restore) #endif +#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10) +#define MS 10000000 + +static void win_init_time(void) +{ + /* The following is used by time functions */ + FILETIME ft; + LARGE_INTEGER li, t_cnt; + + DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency)); + + if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0) + query_performance_frequency= 0; + else + { + GetSystemTimeAsFileTime(&ft); + li.LowPart= ft.dwLowDateTime; + li.HighPart= ft.dwHighDateTime; + query_performance_offset= li.QuadPart-OFFSET_TO_EPOC; + QueryPerformanceCounter(&t_cnt); + query_performance_offset-= (t_cnt.QuadPart / + query_performance_frequency * MS + + t_cnt.QuadPart % + query_performance_frequency * MS / + query_performance_frequency); + } +} + + +/* + Open HKEY_LOCAL_MACHINE\SOFTWARE\MySQL and set any strings found + there as environment variables +*/ +static void win_init_registry(void) +{ + HKEY key_handle; + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)"SOFTWARE\\MySQL", + 0, KEY_READ, &key_handle) == ERROR_SUCCESS) + { + LONG ret; + DWORD index= 0; + DWORD type; + char key_name[256], key_data[1024]; + DWORD key_name_len= sizeof(key_name) - 1; + DWORD key_data_len= sizeof(key_data) - 1; + + while ((ret= RegEnumValue(key_handle, index++, + key_name, &key_name_len, + NULL, &type, (LPBYTE)&key_data, + &key_data_len)) != ERROR_NO_MORE_ITEMS) + { + char env_string[sizeof(key_name) + sizeof(key_data) + 2]; + + if (ret == ERROR_MORE_DATA) + { + /* Registry value larger than 'key_data', skip it */ + DBUG_PRINT("error", ("Skipped registry value that was too large")); + } + else if (ret == ERROR_SUCCESS) + { + if (type == REG_SZ) + { + strxmov(env_string, key_name, "=", key_data, NullS); + + /* variable for putenv must be allocated ! */ + putenv(strdup(env_string)) ; + } + } + else + { + /* Unhandled error, break out of loop */ + break; + } + + key_name_len= sizeof(key_name) - 1; + key_data_len= sizeof(key_data) - 1; + } + + RegCloseKey(key_handle); + } +} + static void my_win_init(void) { @@ -318,17 +401,18 @@ static void my_win_init(void) #if defined(_MSC_VER) #if _MSC_VER < 1300 - /* + /* Clear the OS system variable TZ and avoid the 100% CPU usage Only for old versions of Visual C++ */ - _putenv( "TZ=" ); -#endif + _putenv("TZ="); +#endif #if _MSC_VER >= 1400 /* this is required to make crt functions return -1 appropriately */ _set_invalid_parameter_handler(my_parameter_handler); #endif -#endif +#endif + #ifdef __MSVC_RUNTIME_CHECKS /* Install handler to send RTC (Runtime Error Check) warnings @@ -339,106 +423,10 @@ static void my_win_init(void) _tzset(); - - - - - - - - - - - - - - - - - - - - - - - - - /* The following is used by time functions */ -#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10) -#define MS 10000000 - { - FILETIME ft; - LARGE_INTEGER li, t_cnt; - DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency)); - if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0) - query_performance_frequency= 0; - else - { - GetSystemTimeAsFileTime(&ft); - li.LowPart= ft.dwLowDateTime; - li.HighPart= ft.dwHighDateTime; - query_performance_offset= li.QuadPart-OFFSET_TO_EPOC; - QueryPerformanceCounter(&t_cnt); - query_performance_offset-= (t_cnt.QuadPart / - query_performance_frequency * MS + - t_cnt.QuadPart % - query_performance_frequency * MS / - query_performance_frequency); - } - } + win_init_time(); + win_init_registry(); - { - /* - Open HKEY_LOCAL_MACHINE\SOFTWARE\MySQL and set any strings found - there as environment variables - */ - HKEY key_handle; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)"SOFTWARE\\MySQL", - 0, KEY_READ, &key_handle) == ERROR_SUCCESS) - { - LONG ret; - DWORD index= 0; - DWORD type; - char key_name[256], key_data[1024]; - DWORD key_name_len= sizeof(key_name) - 1; - DWORD key_data_len= sizeof(key_data) - 1; - - while ((ret= RegEnumValue(key_handle, index++, - key_name, &key_name_len, - NULL, &type, (LPBYTE)&key_data, - &key_data_len)) != ERROR_NO_MORE_ITEMS) - { - char env_string[sizeof(key_name) + sizeof(key_data) + 2]; - - if (ret == ERROR_MORE_DATA) - { - /* Registry value larger than 'key_data', skip it */ - DBUG_PRINT("error", ("Skipped registry value that was too large")); - } - else if (ret == ERROR_SUCCESS) - { - if (type == REG_SZ) - { - strxmov(env_string, key_name, "=", key_data, NullS); - - /* variable for putenv must be allocated ! */ - putenv(strdup(env_string)) ; - } - } - else - { - /* Unhandled error, break out of loop */ - break; - } - - key_name_len= sizeof(key_name) - 1; - key_data_len= sizeof(key_data) - 1; - } - - RegCloseKey(key_handle) ; - } - } - DBUG_VOID_RETURN ; + DBUG_VOID_RETURN; } From 995ce0bb0aaaa52116d3a2532a32d91f0d416232 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 15 Dec 2010 08:30:09 -0200 Subject: [PATCH 098/110] Bug#58871: Reorganize maintainer mode compiler flags to allow option for specific compilers Reorganize the maintainer mode cmake code to allow options for specific compilers. For now, enable -Wcheck for ICC, but do not turn warnings into errors. --- CMakeLists.txt | 34 +++++++++++--------------- cmake/maintainer.cmake | 54 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 cmake/maintainer.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 07809a8e29b..059d68e0a3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,30 +115,24 @@ ENDIF() # Control aspects of the development environment which are # specific to MySQL maintainers and developers. # -INCLUDE (CheckCCompilerFlag) -OPTION(MYSQL_MAINTAINER_MODE "MySQL maintainer-specific development environment" OFF) -# Whether the maintainer mode should be enabled. +INCLUDE(maintainer) + +OPTION(MYSQL_MAINTAINER_MODE + "MySQL maintainer-specific development environment" OFF) + +# Whether the maintainer mode compiler options should be enabled. IF(MYSQL_MAINTAINER_MODE) - IF(CMAKE_COMPILER_IS_GNUCC) - CHECK_C_COMPILER_FLAG("-Wdeclaration-after-statement" HAVE_DECLARATION_AFTER_STATEMENT) - IF(HAVE_DECLARATION_AFTER_STATEMENT) - SET(MY_MAINTAINER_DECLARATION_AFTER_STATEMENT "-Wdeclaration-after-statement") - ENDIF() - SET(MY_MAINTAINER_C_WARNINGS - "-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing -Werror") + IF(CMAKE_C_COMPILER_ID MATCHES "GNU") + SET_MYSQL_MAINTAINER_GNU_C_OPTIONS() ENDIF() - IF(CMAKE_COMPILER_IS_GNUCXX) - SET(MY_MAINTAINER_CXX_WARNINGS "${MY_MAINTAINER_C_WARNINGS} -Wno-unused-parameter" - CACHE STRING "C++ warning options used in maintainer builds.") + IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + SET_MYSQL_MAINTAINER_GNU_CXX_OPTIONS() ENDIF() - IF(CMAKE_COMPILER_IS_GNUCC) - SET(MY_MAINTAINER_C_WARNINGS - "${MY_MAINTAINER_C_WARNINGS} ${MY_MAINTAINER_DECLARATION_AFTER_STATEMENT}" - CACHE STRING "C warning options used in maintainer builds.") + IF(CMAKE_C_COMPILER_ID MATCHES "Intel") + SET_MYSQL_MAINTAINER_INTEL_C_OPTIONS() ENDIF() - # Do not make warnings in checks into errors. - IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_COMPILER_IS_GNUCXX) - SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Wno-error") + IF(CMAKE_CXX_COMPILER_ID MATCHES "Intel") + SET_MYSQL_MAINTAINER_INTEL_CXX_OPTIONS() ENDIF() ENDIF() diff --git a/cmake/maintainer.cmake b/cmake/maintainer.cmake new file mode 100644 index 00000000000..468b2f40084 --- /dev/null +++ b/cmake/maintainer.cmake @@ -0,0 +1,54 @@ +# 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(CheckCCompilerFlag) + +# Setup GCC (GNU C compiler) warning options. +MACRO(SET_MYSQL_MAINTAINER_GNU_C_OPTIONS) + SET(MY_MAINTAINER_WARNINGS + "-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing -Werror") + CHECK_C_COMPILER_FLAG("-Wdeclaration-after-statement" + HAVE_DECLARATION_AFTER_STATEMENT) + IF(HAVE_DECLARATION_AFTER_STATEMENT) + SET(MY_MAINTAINER_DECLARATION_AFTER_STATEMENT + "-Wdeclaration-after-statement") + ENDIF() + SET(MY_MAINTAINER_C_WARNINGS + "${MY_MAINTAINER_WARNINGS} ${MY_MAINTAINER_DECLARATION_AFTER_STATEMENT}" + CACHE STRING "C warning options used in maintainer builds.") + # Do not make warnings in checks into errors. + SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Wno-error") +ENDMACRO() + +# Setup G++ (GNU C++ compiler) warning options. +MACRO(SET_MYSQL_MAINTAINER_GNU_CXX_OPTIONS) + SET(MY_MAINTAINER_CXX_WARNINGS + "${MY_MAINTAINER_WARNINGS} -Wno-unused-parameter" + CACHE STRING "C++ warning options used in maintainer builds.") +ENDMACRO() + +# Setup ICC (Intel C Compiler) warning options. +MACRO(SET_MYSQL_MAINTAINER_INTEL_C_OPTIONS) + SET(MY_MAINTAINER_WARNINGS "-Wcheck") + SET(MY_MAINTAINER_C_WARNINGS "${MY_MAINTAINER_WARNINGS}" + CACHE STRING "C warning options used in maintainer builds.") +ENDMACRO() + +# Setup ICPC (Intel C++ Compiler) warning options. +MACRO(SET_MYSQL_MAINTAINER_INTEL_CXX_OPTIONS) + SET(MY_MAINTAINER_CXX_WARNINGS "${MY_MAINTAINER_WARNINGS}" + CACHE STRING "C++ warning options used in maintainer builds.") +ENDMACRO() + From 81605310fda77e64a24fc3492c861feca5252070 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 15 Dec 2010 10:22:05 -0200 Subject: [PATCH 099/110] Add VERSION.dep to the bzr ignore list. The file is generated automatically to place a dependency on the VERSION file. --- .bzrignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.bzrignore b/.bzrignore index 30ed8d438ee..40f6112020e 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3113,3 +3113,4 @@ libmysqld/mysqlserver_depends.c libmysqld/examples/mysql_embedded sql/.empty mysys/thr_lock +VERSION.dep From eb5a21dd909b2001235c7b8cf05075ebc170f6ea Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 15 Dec 2010 20:38:43 -0200 Subject: [PATCH 100/110] Bug#58953: 5.5 does not build with -DWITHOUT_PERFSCHEMA_STORAGE_ENGINE=1 The MYSQL_LOG::open member function does not take a PSI key file argument when the PSI interface is not present. --- sql/log.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/log.cc b/sql/log.cc index 4873cfd49c3..d8c37c5cf5d 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2981,7 +2981,10 @@ bool MYSQL_BIN_LOG::open(const char *log_name, write_error= 0; /* open the main log file */ - if (MYSQL_LOG::open(key_file_binlog, + if (MYSQL_LOG::open( +#ifdef HAVE_PSI_INTERFACE + key_file_binlog, +#endif log_name, log_type_arg, new_name, io_cache_type_arg)) { #ifdef HAVE_REPLICATION From 487f9bb219318ec804659f0fafa5d0e94d587786 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 15 Dec 2010 20:59:21 -0200 Subject: [PATCH 101/110] Bug#58136: Crash in vio_close at concurrent disconnect and KILL The problem is a race between a session closing its vio (i.e. after a COM_QUIT) at the same time it is being killed by another thread. This could trigger a assertion in vio_close() as the two threads could end up closing the same vio, at the same time. This could happen due to the implementation of SIGNAL_WITH_VIO_CLOSE, which closes the vio of the thread being killed. The solution is to serialize the close of the Vio under LOCK_thd_data, which protects THD data. No regression test is added as this is essentially a debug issue and the test case would be quite convoluted as we would need to synchronize a session that is being killed -- which is a bit difficult since debug sync points code does not synchronize killed sessions. --- sql/mysqld.cc | 45 +++++++++++++++++---------------------------- sql/mysqld.h | 2 +- sql/sql_class.cc | 34 ++++++++++++++++++++++++++++++++++ sql/sql_class.h | 3 +++ sql/sql_connect.cc | 6 +++--- sql/sql_parse.cc | 2 +- 6 files changed, 59 insertions(+), 33 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5fb63fb61ba..68795ca377b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1134,7 +1134,7 @@ static void close_connections(void) tmp->thread_id, (tmp->main_security_ctx.user ? tmp->main_security_ctx.user : "")); - close_connection(tmp,0,0); + close_connection(tmp); } #endif DBUG_PRINT("quit",("Unlocking LOCK_thread_count")); @@ -1960,39 +1960,28 @@ static void network_init(void) /** Close a connection. - @param thd Thread handle - @param errcode Error code to print to console - @param lock 1 if we have have to lock LOCK_thread_count + @param thd Thread handle. + @param sql_errno The error code to send before disconnect. @note For the connection that is doing shutdown, this is called twice */ -void close_connection(THD *thd, uint errcode, bool lock) +void close_connection(THD *thd, uint sql_errno) { - st_vio *vio; DBUG_ENTER("close_connection"); - DBUG_PRINT("enter",("fd: %s error: '%s'", - thd->net.vio ? vio_description(thd->net.vio) : - "(not connected)", - errcode ? ER_DEFAULT(errcode) : "")); - if (lock) - mysql_mutex_lock(&LOCK_thread_count); - thd->killed= THD::KILL_CONNECTION; - if ((vio= thd->net.vio) != 0) - { - if (errcode) - net_send_error(thd, errcode, - ER_DEFAULT(errcode), NULL); /* purecov: inspected */ - vio_close(vio); /* vio is freed in delete thd */ - } - if (lock) - mysql_mutex_unlock(&LOCK_thread_count); - MYSQL_CONNECTION_DONE((int) errcode, thd->thread_id); + + if (sql_errno) + net_send_error(thd, sql_errno, ER_DEFAULT(sql_errno), NULL); + + thd->disconnect(); + + MYSQL_CONNECTION_DONE((int) sql_errno, thd->thread_id); + if (MYSQL_CONNECTION_DONE_ENABLED()) { sleep(0); /* Workaround to avoid tailcall optimisation */ } - MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, errcode); + MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, sql_errno); DBUG_VOID_RETURN; } #endif /* EMBEDDED_LIBRARY */ @@ -4951,8 +4940,8 @@ void create_thread_to_handle_connection(THD *thd) my_snprintf(error_message_buff, sizeof(error_message_buff), ER_THD(thd, ER_CANT_CREATE_THREAD), error); net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL); + close_connection(thd); mysql_mutex_lock(&LOCK_thread_count); - close_connection(thd,0,0); delete thd; mysql_mutex_unlock(&LOCK_thread_count); return; @@ -4993,7 +4982,7 @@ static void create_new_thread(THD *thd) mysql_mutex_unlock(&LOCK_connection_count); DBUG_PRINT("error",("Too many connections")); - close_connection(thd, ER_CON_COUNT_ERROR, 1); + close_connection(thd, ER_CON_COUNT_ERROR); delete thd; DBUG_VOID_RETURN; } @@ -5374,7 +5363,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg) if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) || my_net_init(&thd->net, thd->net.vio)) { - close_connection(thd, ER_OUT_OF_RESOURCES, 1); + close_connection(thd, ER_OUT_OF_RESOURCES); delete thd; continue; } @@ -5569,7 +5558,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg) event_conn_closed)) || my_net_init(&thd->net, thd->net.vio)) { - close_connection(thd, ER_OUT_OF_RESOURCES, 1); + close_connection(thd, ER_OUT_OF_RESOURCES); errmsg= 0; goto errorconn; } diff --git a/sql/mysqld.h b/sql/mysqld.h index 5d8885ac277..9218503d477 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -64,7 +64,7 @@ typedef Bitmap<((MAX_INDEXES+7)/8*8)> key_map; /* Used for finding keys */ some places */ /* Function prototypes */ void kill_mysql(void); -void close_connection(THD *thd, uint errcode, bool lock); +void close_connection(THD *thd, uint sql_errno= 0); void handle_connection_in_main_thread(THD *thd); void create_thread_to_handle_connection(THD *thd); void unlink_thd(THD *thd); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2df7a2c8572..c4aa4ba7efb 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1283,6 +1283,40 @@ void THD::awake(THD::killed_state state_to_set) DBUG_VOID_RETURN; } + +/** + Close the Vio associated this session. + + @remark LOCK_thd_data is taken due to the fact that + the Vio might be disassociated concurrently. +*/ + +void THD::disconnect() +{ + Vio *vio= NULL; + + mysql_mutex_lock(&LOCK_thd_data); + + killed= THD::KILL_CONNECTION; + +#ifdef SIGNAL_WITH_VIO_CLOSE + /* + Since a active vio might might have not been set yet, in + any case save a reference to avoid closing a inexistent + one or closing the vio twice if there is a active one. + */ + vio= active_vio; + close_active_vio(); +#endif + + /* Disconnect even if a active vio is not associated. */ + if (net.vio != vio) + vio_close(net.vio); + + mysql_mutex_unlock(&LOCK_thd_data); +} + + /* Remember the location of thread info, the structure needed for sql_alloc() and the structure for the net buffer diff --git a/sql/sql_class.h b/sql/sql_class.h index db20fd73b42..b8e7b685108 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2209,6 +2209,9 @@ public: #endif void awake(THD::killed_state state_to_set); + /** Disconnect the associated communication endpoint. */ + void disconnect(); + #ifndef MYSQL_CLIENT enum enum_binlog_query_type { /* The query can be logged in row format or in statement format. */ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 9799ae14b2f..ad6fe492056 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -518,7 +518,7 @@ bool setup_connection_thread_globals(THD *thd) { if (thd->store_globals()) { - close_connection(thd, ER_OUT_OF_RESOURCES, 1); + close_connection(thd, ER_OUT_OF_RESOURCES); statistic_increment(aborted_connects,&LOCK_status); MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0)); return 1; // Error @@ -693,7 +693,7 @@ void do_handle_one_connection(THD *thd_arg) if (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0)) { - close_connection(thd, ER_OUT_OF_RESOURCES, 1); + close_connection(thd, ER_OUT_OF_RESOURCES); statistic_increment(aborted_connects,&LOCK_status); MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0)); return; @@ -751,7 +751,7 @@ void do_handle_one_connection(THD *thd_arg) end_connection(thd); end_thread: - close_connection(thd, 0, 1); + close_connection(thd); if (MYSQL_CALLBACK_ELSE(thread_scheduler, end_thread, (thd, 1), 0)) return; // Probably no-threads diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index dff6510817f..c4782f37417 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -600,7 +600,7 @@ void do_handle_bootstrap(THD *thd) if (my_thread_init() || thd->store_globals()) { #ifndef EMBEDDED_LIBRARY - close_connection(thd, ER_OUT_OF_RESOURCES, 1); + close_connection(thd, ER_OUT_OF_RESOURCES); #endif thd->fatal_error(); goto end; From caebacaf93a758f5a35f85cb814a5b76402a1f3d Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 16 Dec 2010 09:27:55 +0000 Subject: [PATCH 102/110] bug#58955: Must -DBUILD_CONFIG=mysql_release require libaio on Linux Allow users to build without aio if they really want to, by passing -DIGNORE_AIO_CHECK to cmake. --- .../build_configurations/mysql_release.cmake | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index 1838b0bb669..91d598db465 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -118,17 +118,21 @@ IF(UNIX) OPTION(WITH_PIC "" ON) # Why? IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") - # Ensure aio is available on Linux (required by InnoDB) - CHECK_INCLUDE_FILES(libaio.h HAVE_LIBAIO_H) - CHECK_LIBRARY_EXISTS(aio io_queue_init "" HAVE_LIBAIO) - IF(NOT HAVE_LIBAIO_H OR NOT HAVE_LIBAIO) - MESSAGE(FATAL_ERROR " - aio is required on Linux, you need to install the required library: + IF(NOT IGNORE_AIO_CHECK) + # Ensure aio is available on Linux (required by InnoDB) + CHECK_INCLUDE_FILES(libaio.h HAVE_LIBAIO_H) + CHECK_LIBRARY_EXISTS(aio io_queue_init "" HAVE_LIBAIO) + IF(NOT HAVE_LIBAIO_H OR NOT HAVE_LIBAIO) + MESSAGE(FATAL_ERROR " + aio is required on Linux, you need to install the required library: - Debian/Ubuntu: apt-get install libaio-dev - RedHat/Fedora/Oracle Linux: yum install libaio-devel - SuSE: zypper install libaio-devel - ") + Debian/Ubuntu: apt-get install libaio-dev + RedHat/Fedora/Oracle Linux: yum install libaio-devel + SuSE: zypper install libaio-devel + + If you really do not want it, pass -DIGNORE_AIO_CHECK to cmake. + ") + ENDIF() ENDIF() # Enable fast mutexes on Linux From 28a5059a92707e009aada358bf103fa386ea7c2c Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Thu, 16 Dec 2010 10:55:23 +0100 Subject: [PATCH 103/110] Bug #58730 Assertion failed: table->key_read == 0 in close_thread_table, temptable views The TABLE::key_read field indicates if the optimizer has found that row retrieval only should access the index tree. The triggered assert inside close_thread_table() checks that this field has been reset when the table is about to be closed. During normal execution, these fields are reset right before tables are closed at the end of mysql_execute_command(). But in the case of errors, tables are closed earlier. The patch for Bug#52044 refactored the open tables code so that close_thread_tables() is called immediately if opening of tables fails. At this point in the execution, it could happend that all TABLE::key_read fields had not been properly reset, therefore triggering the assert. The problematic statement in this case was EXPLAIN where the query accessed two derived tables and where the first derived table was processed successfully while the second derived table was not. Since it was an EXPLAIN, TABLE::key_read fields were not reset after successful derived table processing since the state needs to be accessible afterwards. When processing of the second derived table failed, it's corresponding SELECT_LEX_UNIT was cleaned, which caused it's TABLE::key_read fields to be reset. Since processing failed, the error path of open_and_lock_tables() was entered and close_thread_tables() was called. The assert was then triggered due to the TABLE::key_read fields set during processing of the first derived table. This patch fixes the problem by adding a new derived table processor, mysql_derived_cleanup() that is called after mysql_derived_filling(). It causes cleanup of all SELECT_LEX_UNITs to be called, resetting all relevant TABLE::key_read fields. Test case added to derived.test. --- mysql-test/r/derived.result | 15 +++++++++++++++ mysql-test/t/derived.test | 22 ++++++++++++++++++++++ sql/sql_base.cc | 18 +++++++++++++----- sql/sql_derived.cc | 18 +++++++++++++----- sql/sql_derived.h | 12 ++++++++++++ sql/sql_update.cc | 16 +++++++++++++--- 6 files changed, 88 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index d5a0c320d60..a86eabc3192 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -412,3 +412,18 @@ MIN(i) 1 DROP TABLE t1; # End of 5.0 tests +# +# Bug#58730 Assertion failed: table->key_read == 0 in close_thread_table, +# temptable views +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT, KEY (b)); +INSERT INTO t1 VALUES (1),(1); +INSERT INTO t2 VALUES (1),(1); +CREATE algorithm=temptable VIEW v1 AS +SELECT 1 FROM t1 LEFT JOIN t1 t3 ON 1 > (SELECT 1 FROM t1); +CREATE algorithm=temptable VIEW v2 AS SELECT 1 FROM t2; +EXPLAIN SELECT 1 FROM t1 JOIN v1 ON 1 > (SELECT 1 FROM v2); +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t1, t2; +DROP VIEW v1, v2; diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index 939d370cc78..9711482c639 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -313,3 +313,25 @@ WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3; DROP TABLE t1; --echo # End of 5.0 tests + + +--echo # +--echo # Bug#58730 Assertion failed: table->key_read == 0 in close_thread_table, +--echo # temptable views +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT, KEY (b)); +INSERT INTO t1 VALUES (1),(1); +INSERT INTO t2 VALUES (1),(1); + +CREATE algorithm=temptable VIEW v1 AS + SELECT 1 FROM t1 LEFT JOIN t1 t3 ON 1 > (SELECT 1 FROM t1); +CREATE algorithm=temptable VIEW v2 AS SELECT 1 FROM t2; + +# This caused the assert to be triggered. +--error ER_SUBQUERY_NO_1_ROW +EXPLAIN SELECT 1 FROM t1 JOIN v1 ON 1 > (SELECT 1 FROM v2); + +DROP TABLE t1, t2; +DROP VIEW v1, v2; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 60c32a1a376..82302d9da30 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5408,11 +5408,19 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, if (lock_tables(thd, tables, counter, flags)) goto err; - if (derived && - (mysql_handle_derived(thd->lex, &mysql_derived_prepare) || - (thd->fill_derived_tables() && - mysql_handle_derived(thd->lex, &mysql_derived_filling)))) - goto err; + if (derived) + { + if (mysql_handle_derived(thd->lex, &mysql_derived_prepare)) + goto err; + if (thd->fill_derived_tables() && + mysql_handle_derived(thd->lex, &mysql_derived_filling)) + { + mysql_handle_derived(thd->lex, &mysql_derived_cleanup); + goto err; + } + if (!thd->lex->describe) + mysql_handle_derived(thd->lex, &mysql_derived_cleanup); + } DBUG_RETURN(FALSE); err: diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 4a7b3e98935..9b1b9353a23 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -307,13 +307,21 @@ bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *orig_table_list) */ if (derived_result->flush()) res= TRUE; - - if (!lex->describe) - unit->cleanup(); } - else - unit->cleanup(); lex->current_select= save_current_select; } return res; } + + +/** + Cleans up the SELECT_LEX_UNIT for the derived table (if any). +*/ + +bool mysql_derived_cleanup(THD *thd, LEX *lex, TABLE_LIST *derived) +{ + SELECT_LEX_UNIT *unit= derived->derived; + if (unit) + unit->cleanup(); + return false; +} diff --git a/sql/sql_derived.h b/sql/sql_derived.h index 0d4eddedf22..11a6fd4105e 100644 --- a/sql/sql_derived.h +++ b/sql/sql_derived.h @@ -26,4 +26,16 @@ bool mysql_handle_derived(LEX *lex, bool (*processor)(THD *thd, bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t); bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t); +/** + Cleans up the SELECT_LEX_UNIT for the derived table (if any). + + @param thd Thread handler + @param lex LEX for this thread + @param derived TABLE_LIST for the derived table + + @retval false Success + @retval true Failure +*/ +bool mysql_derived_cleanup(THD *thd, LEX *lex, TABLE_LIST *derived); + #endif /* SQL_DERIVED_INCLUDED */ diff --git a/sql/sql_update.cc b/sql/sql_update.cc index b49ed2beafe..082c603bb5a 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -296,11 +296,17 @@ int mysql_update(THD *thd, if (lock_tables(thd, table_list, table_count, 0)) DBUG_RETURN(1); - if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) || - (thd->fill_derived_tables() && - mysql_handle_derived(thd->lex, &mysql_derived_filling))) + if (mysql_handle_derived(thd->lex, &mysql_derived_prepare)) DBUG_RETURN(1); + if (thd->fill_derived_tables() && + mysql_handle_derived(thd->lex, &mysql_derived_filling)) + { + mysql_handle_derived(thd->lex, &mysql_derived_cleanup); + DBUG_RETURN(1); + } + mysql_handle_derived(thd->lex, &mysql_derived_cleanup); + thd_proc_info(thd, "init"); table= table_list->table; @@ -1194,7 +1200,11 @@ int mysql_multi_update_prepare(THD *thd) if (thd->fill_derived_tables() && mysql_handle_derived(lex, &mysql_derived_filling)) + { + mysql_handle_derived(lex, &mysql_derived_cleanup); DBUG_RETURN(TRUE); + } + mysql_handle_derived(lex, &mysql_derived_cleanup); DBUG_RETURN (FALSE); } From 664f06de7c357f30b99dd8c94e6d1092c8e2d4f4 Mon Sep 17 00:00:00 2001 From: Jorgen Loland Date: Thu, 16 Dec 2010 12:25:02 +0100 Subject: [PATCH 104/110] BUG#58456 - Assertion 0 in QUICK_INDEX_MERGE_SELECT::need_sorted_output in opt_range.h In this bug, there are two alternative access plans: * Index merge range access * Const ref access best_access_path() decided that the ref access was preferrable, but make_join_select() still decided to point SQL_SELECT::quick to the index merge because the table had type==JT_CONST which was not handled. At the same time the table's ref.key still referred to the index the ref access would use indicating that ref access should be used. In this state, different parts of the optimizer code have different perceptions of which access path is in use (ref or range). test_if_skip_sort_order() was called to check if the ref access needed ordering, but test_if_skip_sort_order() got confused and requested the index merge to return records in sorted order. Index merge cannot do this, and fired an ASSERT. The fix is to take join_tab->type==JT_CONST into concideration when make_join_select() decides whether or not to use the range access method. --- mysql-test/r/join_outer_innodb.result | 35 +++++++++++++++++++++++++ mysql-test/t/join_outer_innodb.test | 37 +++++++++++++++++++++++++++ sql/sql_select.cc | 16 +++++++----- 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/join_outer_innodb.result b/mysql-test/r/join_outer_innodb.result index e8a2d6f668b..7f6d4fb8553 100644 --- a/mysql-test/r/join_outer_innodb.result +++ b/mysql-test/r/join_outer_innodb.result @@ -17,3 +17,38 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where DROP TABLE t1,t2; +# +# BUG#58456: Assertion 0 in QUICK_INDEX_MERGE_SELECT::need_sorted_output +# in opt_range.h +# +CREATE TABLE t1 ( +col_int INT, +col_int_key INT, +pk INT NOT NULL, +PRIMARY KEY (pk), +KEY col_int_key (col_int_key) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL,1,1), (6,2,2), (5,3,3), (NULL,4,4); +INSERT INTO t1 VALUES (1,NULL,6), (8,5,7), (NULL,8,8), (8,NULL,5); +CREATE TABLE t2 ( +pk INT PRIMARY KEY +) ENGINE=InnoDB; + +EXPLAIN SELECT t1.pk +FROM t2 LEFT JOIN t1 ON t2.pk = t1.col_int +WHERE t1.col_int_key BETWEEN 5 AND 6 +AND t1.pk IS NULL OR t1.pk IN (5) +ORDER BY pk; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY,col_int_key PRIMARY 4 const 2 Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.col_int 1 Using index + +SELECT t1.pk +FROM t2 LEFT JOIN t1 ON t2.pk = t1.col_int +WHERE t1.col_int_key BETWEEN 5 AND 6 +AND t1.pk IS NULL OR t1.pk IN (5) +ORDER BY pk; +pk + +DROP TABLE t1,t2; +# End BUG#58456 diff --git a/mysql-test/t/join_outer_innodb.test b/mysql-test/t/join_outer_innodb.test index 40add7f488f..0d47c4ea57b 100644 --- a/mysql-test/t/join_outer_innodb.test +++ b/mysql-test/t/join_outer_innodb.test @@ -24,3 +24,40 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id WHERE t1.name LIKE 'A%' OR FALSE; DROP TABLE t1,t2; + +--echo # +--echo # BUG#58456: Assertion 0 in QUICK_INDEX_MERGE_SELECT::need_sorted_output +--echo # in opt_range.h +--echo # + +CREATE TABLE t1 ( + col_int INT, + col_int_key INT, + pk INT NOT NULL, + PRIMARY KEY (pk), + KEY col_int_key (col_int_key) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (NULL,1,1), (6,2,2), (5,3,3), (NULL,4,4); +INSERT INTO t1 VALUES (1,NULL,6), (8,5,7), (NULL,8,8), (8,NULL,5); + +CREATE TABLE t2 ( + pk INT PRIMARY KEY +) ENGINE=InnoDB; + +let $query= +SELECT t1.pk +FROM t2 LEFT JOIN t1 ON t2.pk = t1.col_int +WHERE t1.col_int_key BETWEEN 5 AND 6 + AND t1.pk IS NULL OR t1.pk IN (5) +ORDER BY pk; + +--echo +--eval EXPLAIN $query +--echo +--eval $query +--echo + +DROP TABLE t1,t2; + +--echo # End BUG#58456 diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e5d574192b1..90a8727c56c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6499,10 +6499,12 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { /* Use quick key read if it's a constant and it's not used with key reading */ - if (tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF - && tab->type != JT_FT && (tab->type != JT_REF || - (uint) tab->ref.key == tab->quick->index)) - { + if (tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF && + tab->type != JT_FT && + ((tab->type != JT_CONST && tab->type != JT_REF) || + (uint)tab->ref.key == tab->quick->index)) + { + DBUG_ASSERT(tab->quick->index != MAX_KEY); sel->quick=tab->quick; // Use value from get_quick_... sel->quick_keys.clear_all(); sel->needed_reg.clear_all(); @@ -13857,7 +13859,7 @@ check_reverse_order: SYNOPSIS create_sort_index() thd Thread handler - tab Table to sort (in join structure) + join Join with table to sort order How table should be sorted filesort_limit Max number of rows that needs to be sorted select_limit Max number of rows in final output @@ -13867,8 +13869,8 @@ check_reverse_order: IMPLEMENTATION - - If there is an index that can be used, 'tab' is modified to use - this index. + - If there is an index that can be used, the first non-const join_tab in + 'join' is modified to use this index. - If no index, create with filesort() an index file that can be used to retrieve rows in order (should be done with 'read_record'). The sorted data is stored in tab->table and will be freed when calling From 9e161d30218ec367a1398c723d0234820a5f7c55 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 17 Dec 2010 01:17:03 +0000 Subject: [PATCH 105/110] BUG#46166 Post-push fixes: - fixed platform dependent result files - appeasing valgrind warnings: Fault injection was also uncovering a previously existing potential mem leaks. For BUG#46166 testing purposes, fixed by forcing handling the leak when injecting faults. --- mysql-test/suite/binlog/r/binlog_index.result | 4 ++-- mysql-test/suite/binlog/t/binlog_index.test | 2 ++ .../suite/rpl/r/rpl_binlog_errors.result | 12 ++++++------ mysql-test/suite/rpl/t/rpl_binlog_errors.test | 8 +++++--- sql/log.cc | 18 ++++++++++++++++++ 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_index.result b/mysql-test/suite/binlog/r/binlog_index.result index 6b422b82191..11cf43b8a5e 100644 --- a/mysql-test/suite/binlog/r/binlog_index.result +++ b/mysql-test/suite/binlog/r/binlog_index.result @@ -132,7 +132,7 @@ master-bin.000011 # fault_injection_registering_index SET SESSION debug="+d,fault_injection_registering_index"; flush logs; -ERROR HY000: Can't open file: './master-bin.000012' (errno: 1) +ERROR HY000: Can't open file: 'master-bin.000012' (errno: 1) SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); SELECT @index; @index @@ -157,7 +157,7 @@ master-bin.000012 # fault_injection_updating_index SET SESSION debug="+d,fault_injection_updating_index"; flush logs; -ERROR HY000: Can't open file: './master-bin.000013' (errno: 1) +ERROR HY000: Can't open file: 'master-bin.000013' (errno: 1) SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); SELECT @index; @index diff --git a/mysql-test/suite/binlog/t/binlog_index.test b/mysql-test/suite/binlog/t/binlog_index.test index d2b34083182..b735574fdb9 100644 --- a/mysql-test/suite/binlog/t/binlog_index.test +++ b/mysql-test/suite/binlog/t/binlog_index.test @@ -218,6 +218,7 @@ SELECT @index; --echo # fault_injection_registering_index SET SESSION debug="+d,fault_injection_registering_index"; +-- replace_regex /\.[\\\/]master/master/ -- error ER_CANT_OPEN_FILE flush logs; @@ -237,6 +238,7 @@ SELECT @index; --echo # fault_injection_updating_index SET SESSION debug="+d,fault_injection_updating_index"; +-- replace_regex /\.[\\\/]master/master/ -- error ER_CANT_OPEN_FILE flush logs; diff --git a/mysql-test/suite/rpl/r/rpl_binlog_errors.result b/mysql-test/suite/rpl/r/rpl_binlog_errors.result index e67b60860ca..6c8c750bc79 100644 --- a/mysql-test/suite/rpl/r/rpl_binlog_errors.result +++ b/mysql-test/suite/rpl/r/rpl_binlog_errors.result @@ -35,9 +35,9 @@ master-bin.000001 # SET GLOBAL debug=""; RESET MASTER; ###################### TEST #3 -CREATE TABLE t1 (a int); -CREATE TABLE t2 (a TEXT) Engine=InnoDB; -CREATE TABLE t4 (a TEXT); +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a VARCHAR(16384)) Engine=InnoDB; +CREATE TABLE t4 (a VARCHAR(16384)); INSERT INTO t1 VALUES (1); RESET MASTER; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t2; @@ -181,7 +181,7 @@ SHOW WARNINGS; Level Code Message SET GLOBAL debug="+d,fault_injection_registering_index"; FLUSH LOGS; -ERROR HY000: Can't open file: './master-bin.000002' (errno: 1) +ERROR HY000: Can't open file: 'master-bin.000002' (errno: 1) SET GLOBAL debug="-d,fault_injection_registering_index"; SHOW BINARY LOGS; ERROR HY000: You are not using binary logging @@ -194,7 +194,7 @@ DROP TABLE t5; ###################### TEST #11 SET GLOBAL debug="+d,fault_injection_openning_index"; FLUSH LOGS; -ERROR HY000: Can't open file: './master-bin.index' (errno: 1) +ERROR HY000: Can't open file: 'master-bin.index' (errno: 1) SET GLOBAL debug="-d,fault_injection_openning_index"; RESET MASTER; ERROR HY000: Binlog closed, cannot RESET MASTER @@ -207,7 +207,7 @@ DROP TABLE t5; ###################### TEST #12 SET GLOBAL debug="+d,fault_injection_new_file_rotate_event"; FLUSH LOGS; -ERROR HY000: Can't open file: 'master-bin' (errno: 0) +ERROR HY000: Can't open file: 'master-bin' (errno: 2) SET GLOBAL debug="-d,fault_injection_new_file_rotate_event"; RESET MASTER; ERROR HY000: Binlog closed, cannot RESET MASTER diff --git a/mysql-test/suite/rpl/t/rpl_binlog_errors.test b/mysql-test/suite/rpl/t/rpl_binlog_errors.test index ae83659a38a..e4eb212e1cd 100644 --- a/mysql-test/suite/rpl/t/rpl_binlog_errors.test +++ b/mysql-test/suite/rpl/t/rpl_binlog_errors.test @@ -82,9 +82,9 @@ RESET MASTER; ### ACTION: create some tables (t1, t2, t4) and insert some values in ### table t1 -CREATE TABLE t1 (a int); -CREATE TABLE t2 (a TEXT) Engine=InnoDB; -CREATE TABLE t4 (a TEXT); +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a VARCHAR(16384)) Engine=InnoDB; +CREATE TABLE t4 (a VARCHAR(16384)); INSERT INTO t1 VALUES (1); RESET MASTER; @@ -272,6 +272,7 @@ SHOW WARNINGS; # +d,fault_injection_registering_index => injects fault on MYSQL_BIN_LOG::open SET GLOBAL debug="+d,fault_injection_registering_index"; +-- replace_regex /\.[\\\/]master/master/ -- error ER_CANT_OPEN_FILE FLUSH LOGS; SET GLOBAL debug="-d,fault_injection_registering_index"; @@ -298,6 +299,7 @@ DROP TABLE t5; # +d,fault_injection_openning_index => injects fault on MYSQL_BIN_LOG::open_index_file SET GLOBAL debug="+d,fault_injection_openning_index"; +-- replace_regex /\.[\\\/]master/master/ -- error ER_CANT_OPEN_FILE FLUSH LOGS; SET GLOBAL debug="-d,fault_injection_openning_index"; diff --git a/sql/log.cc b/sql/log.cc index 5fcb5fe0367..f3d3420194c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2599,6 +2599,23 @@ bool MYSQL_BIN_LOG::open(const char *log_name, sync_purge_index_file() || DBUG_EVALUATE_IF("fault_injection_registering_index", 1, 0)) { + /** + TODO: although this was introduced to appease valgrind + when injecting emulated faults using fault_injection_registering_index + it may be good to consider what actually happens when + open_purge_index_file succeeds but register or sync fails. + + Perhaps we might need the code below in MYSQL_LOG_BIN::cleanup + for "real life" purposes as well? + */ + DBUG_EXECUTE_IF("fault_injection_registering_index", { + if (my_b_inited(&purge_index_file)) + { + end_io_cache(&purge_index_file); + my_close(purge_index_file.file, MYF(0)); + } + }); + sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file."); DBUG_RETURN(1); } @@ -3827,6 +3844,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) if(DBUG_EVALUATE_IF("fault_injection_new_file_rotate_event", (error=close_on_error=TRUE), FALSE) || (error= r.write(&log_file))) { + DBUG_EXECUTE_IF("fault_injection_new_file_rotate_event", errno=2;); close_on_error= TRUE; my_printf_error(ER_ERROR_ON_WRITE, ER(ER_CANT_OPEN_FILE), MYF(ME_FATALERROR), name, errno); goto end; From 6c3d371441f2c2e4bd112de19a26a66e92932345 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 17 Dec 2010 10:20:44 +0200 Subject: [PATCH 106/110] post-merge test suite update --- mysql-test/suite/binlog/r/binlog_unsafe.result | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result index 6b2a83c9483..b851e472689 100644 --- a/mysql-test/suite/binlog/r/binlog_unsafe.result +++ b/mysql-test/suite/binlog/r/binlog_unsafe.result @@ -28,6 +28,7 @@ Warnings: Note 1592 Statement may not be safe to log in statement format. INSERT INTO t2 VALUES (@@hostname); Warnings: +Warning 1265 Data truncated for column 'a' at row 1 Note 1592 Statement may not be safe to log in statement format. ---- Insert from stored procedure ---- CREATE PROCEDURE proc() @@ -48,6 +49,7 @@ Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. +Warning 1265 Data truncated for column 'a' at row 6 Note 1592 Statement may not be safe to log in statement format. ---- Insert from stored function ---- CREATE FUNCTION func() @@ -72,6 +74,7 @@ Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. +Warning 1265 Data truncated for column 'a' at row 6 Note 1592 Statement may not be safe to log in statement format. ---- Insert from trigger ---- CREATE TRIGGER trig @@ -94,6 +97,7 @@ Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. +Warning 1265 Data truncated for column 'a' at row 6 Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. ---- Insert from prepared statement ---- @@ -124,6 +128,7 @@ Warnings: Note 1592 Statement may not be safe to log in statement format. EXECUTE p7; Warnings: +Warning 1265 Data truncated for column 'a' at row 1 Note 1592 Statement may not be safe to log in statement format. ---- Insert from nested call of triggers / functions / procedures ---- CREATE PROCEDURE proc1() @@ -160,6 +165,7 @@ Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. +Warning 1265 Data truncated for column 'a' at row 6 Note 1592 Statement may not be safe to log in statement format. ==== Variables that should *not* be unsafe ==== INSERT INTO t1 VALUES (@@session.pseudo_thread_id); @@ -303,6 +309,8 @@ INSERT INTO t2 VALUES (@@global.init_slave); INSERT INTO t2 VALUES (@@hostname); END| INSERT INTO trigger_table VALUES ('bye.'); +Warnings: +Warning 1265 Data truncated for column 'a' at row 6 DROP FUNCTION fun_check_log_bin; DROP FUNCTION func6; DROP FUNCTION func7; From 63c1731a64556e08cb81ca4385c72a6395911fd3 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 17 Dec 2010 10:22:54 +0200 Subject: [PATCH 107/110] post-merge test result update --- mysql-test/r/fulltext.result | 9 --------- 1 file changed, 9 deletions(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 8c66156152e..7788a32ac90 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -663,9 +663,6 @@ ON (MATCH(t1.f1) against ("")) WHERE t1.f1 GROUP BY t1.f1)) xor f1; 1 1 -Warnings: -Warning 1292 Truncated incorrect INTEGER value: 'test' -Warning 1292 Truncated incorrect INTEGER value: 'test' PREPARE stmt FROM 'SELECT 1 FROM t1 WHERE 1 > ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a @@ -674,15 +671,9 @@ PREPARE stmt FROM EXECUTE stmt; 1 1 -Warnings: -Warning 1292 Truncated incorrect INTEGER value: 'test' -Warning 1292 Truncated incorrect INTEGER value: 'test' EXECUTE stmt; 1 1 -Warnings: -Warning 1292 Truncated incorrect INTEGER value: 'test' -Warning 1292 Truncated incorrect INTEGER value: 'test' DEALLOCATE PREPARE stmt; PREPARE stmt FROM 'SELECT 1 FROM t1 WHERE 1 > From f7dc30c843912f047fdc1d6f196228c0366b3729 Mon Sep 17 00:00:00 2001 From: Jorgen Loland Date: Fri, 17 Dec 2010 10:02:24 +0100 Subject: [PATCH 108/110] BUG#58985: Assertion tab->quick->index != 64 failed in make_join_select() in sql_select.cc Caused by incorrect ASSERT introduced by BUG#58456. Quick selects may have index == MAX_KEY if it merges indices. --- sql/sql_select.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 90a8727c56c..6e42b65175a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6504,7 +6504,6 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) ((tab->type != JT_CONST && tab->type != JT_REF) || (uint)tab->ref.key == tab->quick->index)) { - DBUG_ASSERT(tab->quick->index != MAX_KEY); sel->quick=tab->quick; // Use value from get_quick_... sel->quick_keys.clear_all(); sel->needed_reg.clear_all(); From eb63f9e705e758a85d9a6d7fa6df63f1dce85423 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Fri, 17 Dec 2010 13:48:00 +0300 Subject: [PATCH 109/110] Merge follow-up: update test result. --- mysql-test/r/fulltext.result | 9 --------- 1 file changed, 9 deletions(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 8c66156152e..7788a32ac90 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -663,9 +663,6 @@ ON (MATCH(t1.f1) against ("")) WHERE t1.f1 GROUP BY t1.f1)) xor f1; 1 1 -Warnings: -Warning 1292 Truncated incorrect INTEGER value: 'test' -Warning 1292 Truncated incorrect INTEGER value: 'test' PREPARE stmt FROM 'SELECT 1 FROM t1 WHERE 1 > ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a @@ -674,15 +671,9 @@ PREPARE stmt FROM EXECUTE stmt; 1 1 -Warnings: -Warning 1292 Truncated incorrect INTEGER value: 'test' -Warning 1292 Truncated incorrect INTEGER value: 'test' EXECUTE stmt; 1 1 -Warnings: -Warning 1292 Truncated incorrect INTEGER value: 'test' -Warning 1292 Truncated incorrect INTEGER value: 'test' DEALLOCATE PREPARE stmt; PREPARE stmt FROM 'SELECT 1 FROM t1 WHERE 1 > From 8165ea21f0d76ebd9de6158cbb559435507b1420 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 17 Dec 2010 14:42:30 +0200 Subject: [PATCH 110/110] tree details update to main --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 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.0-bugteam" +tree_name = "mysql-5.0"