#At file:///home/daogangqu/mysql/bzrwork1/bug51639/mysql-next-mr-bugfixing/ based on revid:marc.alff@stripped
3287 Dao-Gang.Qu@stripped 2010-09-15
Bug #51639 Some replication filters are case sensitive, some are not!
There is an inconsistency in name comparison of rpl filters.
Some are case sensitive, while others are not. And they did
not follow the setting of lower_case_table_names.
To fix the problem to make all the filters follow the setting
of lower_case_table_name to be case sensitive when setting
lower_case_table_name=0. Otherwise they will be case insensitive
but accent sensitive.
@ include/m_ctype.h
Added code to extern my_charset_utf8_tolower_ci
@ mysql-test/suite/rpl/r/rpl_do_filter.result
Test result for BUG# 51639
@ mysql-test/suite/rpl/r/rpl_ignore_db_filter.result
Test result for BUG# 51639
@ mysql-test/suite/rpl/r/rpl_ignore_table_filter.result
Test result for BUG# 51639
@ mysql-test/suite/rpl/r/rpl_rewrite_db_filter.result
Test result for BUG# 51639
@ mysql-test/suite/rpl/t/rpl_do_filter.test
Added test file to verify that 'do db' and 'do table 'filters
will follow the setting of lower_case_table_name to be case
insensitive when setting lower_case_table_name > 0
@ mysql-test/suite/rpl/t/rpl_ignore_db_filter.test
Added test file to verify that 'ignore db' filter will follow
the setting of lower_case_table_name to be case insensitive when
setting lower_case_table_name > 0
@ mysql-test/suite/rpl/t/rpl_ignore_table_filter.test
Added test file to verify that 'wild ignore table' and 'ignore table'
filters will follow the setting of lower_case_table_name to be case
sensitive when setting lower_case_table_name=0
@ mysql-test/suite/rpl/t/rpl_rewrite_db_filter.test
Added test file to verify that 'rewrite db' filter will follow
the setting of lower_case_table_name to be case insensitive
when setting lower_case_table_name > 0
@ sql/mysqld.cc
Added code to build do_table and ignore_table rules to hush
after resetting of table_alias_charset, so that the filters
is affected by the setting of lower_case_table_name
regardless of the setting order.
@ sql/rpl_filter.cc
Added code to make filters follow the setting of lower_case_table_name
to be case sensitive when setting lower_case_table_name=0. Otherwise
they will be case insensitive but accent sensitive. And build do_table
and ignore table rules to Hash from DYNAMIC_ARRAY for faster filter
checking.
@ strings/ctype-utf8.c
Added code to define a new CHARSET_INFO to support
case insensitive but accent sensitive.
added:
mysql-test/extra/rpl_tests/rpl_filters.test
mysql-test/suite/rpl/r/rpl_do_filter.result
mysql-test/suite/rpl/r/rpl_ignore_db_filter.result
mysql-test/suite/rpl/r/rpl_ignore_table_filter.result
mysql-test/suite/rpl/r/rpl_rewrite_db_filter.result
mysql-test/suite/rpl/t/rpl_do_filter-master.opt
mysql-test/suite/rpl/t/rpl_do_filter-slave.opt
mysql-test/suite/rpl/t/rpl_do_filter.test
mysql-test/suite/rpl/t/rpl_ignore_db_filter-master.opt
mysql-test/suite/rpl/t/rpl_ignore_db_filter-slave.opt
mysql-test/suite/rpl/t/rpl_ignore_db_filter.test
mysql-test/suite/rpl/t/rpl_ignore_table_filter-master.opt
mysql-test/suite/rpl/t/rpl_ignore_table_filter-slave.opt
mysql-test/suite/rpl/t/rpl_ignore_table_filter.test
mysql-test/suite/rpl/t/rpl_rewrite_db_filter-master.opt
mysql-test/suite/rpl/t/rpl_rewrite_db_filter-slave.opt
mysql-test/suite/rpl/t/rpl_rewrite_db_filter.test
modified:
include/m_ctype.h
sql/mysqld.cc
sql/rpl_filter.cc
sql/rpl_filter.h
strings/ctype-utf8.c
=== modified file 'include/m_ctype.h'
--- a/include/m_ctype.h 2010-09-01 06:35:04 +0000
+++ b/include/m_ctype.h 2010-09-15 07:31:48 +0000
@@ -154,6 +154,7 @@ extern MY_UNI_CTYPE my_uni_ctype[256];
#define MY_CS_PUREASCII 4096 /* if a charset is pure ascii */
#define MY_CS_NONASCII 8192 /* if not ASCII-compatible */
#define MY_CS_UNICODE_SUPPLEMENT 16384 /* Non-BMP Unicode characters */
+#define MY_CS_LOWER_SORT 32768 /* If use lower case as weight */
#define MY_CHARSET_UNDEFINED 0
/* Character repertoire flags */
@@ -431,6 +432,7 @@ extern CHARSET_INFO my_charset_utf32_gen
extern CHARSET_INFO my_charset_utf32_unicode_ci;
extern CHARSET_INFO my_charset_utf8_general_ci;
+extern CHARSET_INFO my_charset_utf8_tolower_ci;
extern CHARSET_INFO my_charset_utf8_unicode_ci;
extern CHARSET_INFO my_charset_utf8_bin;
extern CHARSET_INFO my_charset_utf8mb4_bin;
=== added file 'mysql-test/extra/rpl_tests/rpl_filters.test'
--- a/mysql-test/extra/rpl_tests/rpl_filters.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_filters.test 2010-09-15 07:31:48 +0000
@@ -0,0 +1,22 @@
+#
+# Bug #51639
+# The common part of Bug #51639 to test filters
+#
+
+CREATE DATABASE mydb;
+USE mydb;
+CREATE TABLE T1 (a INT) ENGINE= MYISAM;
+CREATE TABLE t2 (a INT) ENGINE= MYISAM;
+INSERT INTO T1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+-- echo # On master
+-- source include/show_binlog_events.inc
+
+-- sync_slave_with_master
+-- echo # On slave
+-- source include/show_binlog_events.inc
+
+-- connection master
+DROP DATABASE mydb;
+-- sync_slave_with_master
+
=== added file 'mysql-test/suite/rpl/r/rpl_do_filter.result'
--- a/mysql-test/suite/rpl/r/rpl_do_filter.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_do_filter.result 2010-09-15 07:31:48 +0000
@@ -0,0 +1,38 @@
+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;
+CREATE DATABASE mydb;
+USE mydb;
+CREATE TABLE T1 (a INT) ENGINE= MYISAM;
+CREATE TABLE t2 (a INT) ENGINE= MYISAM;
+INSERT INTO T1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+# On master
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # CREATE DATABASE mydb
+master-bin.000001 # Query # # use `mydb`; CREATE TABLE T1 (a INT) ENGINE= MYISAM
+master-bin.000001 # Query # # use `mydb`; CREATE TABLE t2 (a INT) ENGINE= MYISAM
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `mydb`; INSERT INTO T1 VALUES (1)
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `mydb`; INSERT INTO t2 VALUES (1)
+master-bin.000001 # Query # # COMMIT
+# On slave
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Query # # CREATE DATABASE mydb
+slave-bin.000001 # Query # # use `mydb`; CREATE TABLE T1 (a INT) ENGINE= MYISAM
+slave-bin.000001 # Query # # use `mydb`; CREATE TABLE t2 (a INT) ENGINE= MYISAM
+slave-bin.000001 # Query # # BEGIN
+slave-bin.000001 # Query # # use `mydb`; INSERT INTO T1 VALUES (1)
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Query # # BEGIN
+slave-bin.000001 # Query # # use `mydb`; INSERT INTO t2 VALUES (1)
+slave-bin.000001 # Query # # COMMIT
+DROP DATABASE mydb;
+Replicate_Do_Table: mydb.T2,mydb.T1
=== added file 'mysql-test/suite/rpl/r/rpl_ignore_db_filter.result'
--- a/mysql-test/suite/rpl/r/rpl_ignore_db_filter.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_ignore_db_filter.result 2010-09-15 07:31:48 +0000
@@ -0,0 +1,28 @@
+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;
+CREATE DATABASE mydb;
+USE mydb;
+CREATE TABLE T1 (a INT) ENGINE= MYISAM;
+CREATE TABLE t2 (a INT) ENGINE= MYISAM;
+INSERT INTO T1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+# On master
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # CREATE DATABASE mydb
+master-bin.000001 # Query # # use `mydb`; CREATE TABLE T1 (a INT) ENGINE= MYISAM
+master-bin.000001 # Query # # use `mydb`; CREATE TABLE t2 (a INT) ENGINE= MYISAM
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `mydb`; INSERT INTO T1 VALUES (1)
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `mydb`; INSERT INTO t2 VALUES (1)
+master-bin.000001 # Query # # COMMIT
+# On slave
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+DROP DATABASE mydb;
=== added file 'mysql-test/suite/rpl/r/rpl_ignore_table_filter.result'
--- a/mysql-test/suite/rpl/r/rpl_ignore_table_filter.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_ignore_table_filter.result 2010-09-15 07:31:48 +0000
@@ -0,0 +1,30 @@
+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;
+CREATE DATABASE mydb;
+USE mydb;
+CREATE TABLE T1 (a INT) ENGINE= MYISAM;
+CREATE TABLE t2 (a INT) ENGINE= MYISAM;
+INSERT INTO T1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+# On master
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # CREATE DATABASE mydb
+master-bin.000001 # Query # # use `mydb`; CREATE TABLE T1 (a INT) ENGINE= MYISAM
+master-bin.000001 # Query # # use `mydb`; CREATE TABLE t2 (a INT) ENGINE= MYISAM
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `mydb`; INSERT INTO T1 VALUES (1)
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `mydb`; INSERT INTO t2 VALUES (1)
+master-bin.000001 # Query # # COMMIT
+# On slave
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Query # # CREATE DATABASE mydb
+DROP DATABASE mydb;
+Replicate_Ignore_Table: mydb.t3,mydb.t2
=== added file 'mysql-test/suite/rpl/r/rpl_rewrite_db_filter.result'
--- a/mysql-test/suite/rpl/r/rpl_rewrite_db_filter.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_rewrite_db_filter.result 2010-09-15 07:31:48 +0000
@@ -0,0 +1,40 @@
+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;
+CREATE DATABASE rewrite;
+CREATE DATABASE mydb;
+USE mydb;
+CREATE TABLE T1 (a INT) ENGINE= MYISAM;
+CREATE TABLE t2 (a INT) ENGINE= MYISAM;
+INSERT INTO T1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+# On master
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # CREATE DATABASE mydb
+master-bin.000001 # Query # # use `mydb`; CREATE TABLE T1 (a INT) ENGINE= MYISAM
+master-bin.000001 # Query # # use `mydb`; CREATE TABLE t2 (a INT) ENGINE= MYISAM
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `mydb`; INSERT INTO T1 VALUES (1)
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `mydb`; INSERT INTO t2 VALUES (1)
+master-bin.000001 # Query # # COMMIT
+# On slave
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Query # # CREATE DATABASE rewrite
+slave-bin.000001 # Query # # CREATE DATABASE mydb
+slave-bin.000001 # Query # # use `rewrite`; CREATE TABLE T1 (a INT) ENGINE= MYISAM
+slave-bin.000001 # Query # # use `rewrite`; CREATE TABLE t2 (a INT) ENGINE= MYISAM
+slave-bin.000001 # Query # # BEGIN
+slave-bin.000001 # Query # # use `rewrite`; INSERT INTO T1 VALUES (1)
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Query # # BEGIN
+slave-bin.000001 # Query # # use `rewrite`; INSERT INTO t2 VALUES (1)
+slave-bin.000001 # Query # # COMMIT
+DROP DATABASE mydb;
+DROP DATABASE rewrite;
=== added file 'mysql-test/suite/rpl/t/rpl_do_filter-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_do_filter-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_do_filter-master.opt 2010-09-15 07:31:48 +0000
@@ -0,0 +1 @@
+--lower_case_table_names=1
=== added file 'mysql-test/suite/rpl/t/rpl_do_filter-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_do_filter-slave.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_do_filter-slave.opt 2010-09-15 07:31:48 +0000
@@ -0,0 +1 @@
+--replicate-do-db=MYDB --replicate-do-table=mydb.T1 --replicate-do-table=mydb.T2 --lower_case_table_names=1
=== added file 'mysql-test/suite/rpl/t/rpl_do_filter.test'
--- a/mysql-test/suite/rpl/t/rpl_do_filter.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_do_filter.test 2010-09-15 07:31:48 +0000
@@ -0,0 +1,13 @@
+#
+# Bug #51639
+# This test verifies that 'do db' and 'do table'filters
+# will follow the setting of lower_case_table_name to be
+# case insensitive when setting lower_case_table_name > 0
+#
+
+-- source include/master-slave.inc
+-- source include/have_binlog_format_statement.inc
+
+-- source extra/rpl_tests/rpl_filters.test
+let $replicate_do_table= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Table, 1);
+--echo Replicate_Do_Table: $replicate_do_table
=== added file 'mysql-test/suite/rpl/t/rpl_ignore_db_filter-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_ignore_db_filter-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_ignore_db_filter-master.opt 2010-09-15 07:31:48 +0000
@@ -0,0 +1 @@
+--lower_case_table_names=1
=== added file 'mysql-test/suite/rpl/t/rpl_ignore_db_filter-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_ignore_db_filter-slave.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_ignore_db_filter-slave.opt 2010-09-15 07:31:48 +0000
@@ -0,0 +1 @@
+--replicate-ignore-db=MYDB --lower_case_table_names=1
=== added file 'mysql-test/suite/rpl/t/rpl_ignore_db_filter.test'
--- a/mysql-test/suite/rpl/t/rpl_ignore_db_filter.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_ignore_db_filter.test 2010-09-15 07:31:48 +0000
@@ -0,0 +1,11 @@
+#
+# Bug #51639
+# This test verifies that 'ignore db' filter will follow
+# the setting of lower_case_table_name to be case insensitive
+# when setting lower_case_table_name > 0
+#
+
+-- source include/master-slave.inc
+-- source include/have_binlog_format_statement.inc
+
+-- source extra/rpl_tests/rpl_filters.test
=== added file 'mysql-test/suite/rpl/t/rpl_ignore_table_filter-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_ignore_table_filter-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_ignore_table_filter-master.opt 2010-09-15 07:31:48 +0000
@@ -0,0 +1 @@
+--lower_case_table_names=0
=== added file 'mysql-test/suite/rpl/t/rpl_ignore_table_filter-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_ignore_table_filter-slave.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_ignore_table_filter-slave.opt 2010-09-15 07:31:48 +0000
@@ -0,0 +1 @@
+--replicate-do-db=mydb --replicate-wild-ignore-table=my%.T1 --replicate-ignore-table=mydb.t2 --replicate-ignore-table=mydb.t3 --lower_case_table_names=0
=== added file 'mysql-test/suite/rpl/t/rpl_ignore_table_filter.test'
--- a/mysql-test/suite/rpl/t/rpl_ignore_table_filter.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_ignore_table_filter.test 2010-09-15 07:31:48 +0000
@@ -0,0 +1,13 @@
+#
+# Bug #51639
+# This test verifies that 'ignore table' filter will follow
+# the setting of lower_case_table_name to be case sensitive
+# when setting lower_case_table_name=0
+#
+
+-- source include/master-slave.inc
+-- source include/have_binlog_format_statement.inc
+
+-- source extra/rpl_tests/rpl_filters.test
+let $replicate_ignore_table= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Table, 1);
+--echo Replicate_Ignore_Table: $replicate_ignore_table
=== added file 'mysql-test/suite/rpl/t/rpl_rewrite_db_filter-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_rewrite_db_filter-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_rewrite_db_filter-master.opt 2010-09-15 07:31:48 +0000
@@ -0,0 +1 @@
+--lower_case_table_names=1
=== added file 'mysql-test/suite/rpl/t/rpl_rewrite_db_filter-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_rewrite_db_filter-slave.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_rewrite_db_filter-slave.opt 2010-09-15 07:31:48 +0000
@@ -0,0 +1 @@
+--replicate-rewrite-db=MYDB->rewrite --lower_case_table_names=1
=== added file 'mysql-test/suite/rpl/t/rpl_rewrite_db_filter.test'
--- a/mysql-test/suite/rpl/t/rpl_rewrite_db_filter.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_rewrite_db_filter.test 2010-09-15 07:31:48 +0000
@@ -0,0 +1,17 @@
+#
+# Bug #51639
+# This test verifies that 'rewrite db' filter will follow
+# the setting of lower_case_table_name to be case insensitive
+# when setting lower_case_table_name > 0
+#
+
+-- source include/master-slave.inc
+-- source include/have_binlog_format_statement.inc
+connection slave;
+CREATE DATABASE rewrite;
+
+connection master;
+-- source extra/rpl_tests/rpl_filters.test
+
+connection slave;
+DROP DATABASE rewrite;
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-09-08 07:10:51 +0000
+++ b/sql/mysqld.cc 2010-09-15 07:31:48 +0000
@@ -3492,9 +3492,21 @@ You should consider changing lower_case_
/* Reset table_alias_charset, now that lower_case_table_names is set. */
table_alias_charset= (lower_case_table_names ?
- files_charset_info :
+ &my_charset_utf8_tolower_ci :
&my_charset_bin);
+ /*
+ Build do_table and ignore_table rules to hush
+ after the resetting of table_alias_charset
+ */
+ if (rpl_filter->build_do_table_hash() ||
+ rpl_filter->build_ignore_table_hash())
+ {
+ sql_print_error("An error occurred while building do_table"
+ "and ignore_table rules to hush.");
+ return 1;
+ }
+
return 0;
}
@@ -7125,7 +7137,7 @@ mysqld_get_one_option(int optid,
}
case (int)OPT_REPLICATE_DO_TABLE:
{
- if (rpl_filter->add_do_table(argument))
+ if (rpl_filter->add_do_table_array(argument))
{
sql_print_error("Could not add do table rule '%s'!\n", argument);
return 1;
@@ -7152,7 +7164,7 @@ mysqld_get_one_option(int optid,
}
case (int)OPT_REPLICATE_IGNORE_TABLE:
{
- if (rpl_filter->add_ignore_table(argument))
+ if (rpl_filter->add_ignore_table_array(argument))
{
sql_print_error("Could not add ignore table rule '%s'!\n", argument);
return 1;
=== modified file 'sql/rpl_filter.cc'
--- a/sql/rpl_filter.cc 2010-07-08 21:42:23 +0000
+++ b/sql/rpl_filter.cc 2010-09-15 07:31:48 +0000
@@ -23,8 +23,9 @@
#define TABLE_RULE_ARR_SIZE 16
Rpl_filter::Rpl_filter() :
- table_rules_on(0), do_table_inited(0), ignore_table_inited(0),
- wild_do_table_inited(0), wild_ignore_table_inited(0)
+ table_rules_on(0), do_table_array_inited(0), ignore_table_array_inited(0),
+ wild_do_table_inited(0), wild_ignore_table_inited(0),
+ do_table_hash_inited(0), ignore_table_hash_inited(0)
{
do_db.empty();
ignore_db.empty();
@@ -34,10 +35,14 @@ Rpl_filter::Rpl_filter() :
Rpl_filter::~Rpl_filter()
{
- if (do_table_inited)
- my_hash_free(&do_table);
- if (ignore_table_inited)
- my_hash_free(&ignore_table);
+ if (do_table_hash_inited)
+ my_hash_free(&do_table_hash);
+ if (ignore_table_hash_inited)
+ my_hash_free(&ignore_table_hash);
+ if (do_table_array_inited)
+ free_string_array(&do_table_array);
+ if (ignore_table_array_inited)
+ free_string_array(&ignore_table_array);
if (wild_do_table_inited)
free_string_array(&wild_do_table);
if (wild_ignore_table_inited)
@@ -91,7 +96,7 @@ Rpl_filter::tables_ok(const char* db, TA
{
bool some_tables_updating= 0;
DBUG_ENTER("Rpl_filter::tables_ok");
-
+
for (; tables; tables= tables->next_global)
{
char hash_key[2*NAME_LEN+2];
@@ -104,14 +109,14 @@ Rpl_filter::tables_ok(const char* db, TA
end= strmov(hash_key, tables->db ? tables->db : db);
*end++= '.';
len= (uint) (strmov(end, tables->table_name) - hash_key);
- if (do_table_inited) // if there are any do's
+ if (do_table_hash_inited) // if there are any do's
{
- if (my_hash_search(&do_table, (uchar*) hash_key, len))
+ if (my_hash_search(&do_table_hash, (uchar*) hash_key, len))
DBUG_RETURN(1);
}
- if (ignore_table_inited) // if there are any ignores
+ if (ignore_table_hash_inited) // if there are any ignores
{
- if (my_hash_search(&ignore_table, (uchar*) hash_key, len))
+ if (my_hash_search(&ignore_table_hash, (uchar*) hash_key, len))
DBUG_RETURN(0);
}
if (wild_do_table_inited &&
@@ -129,7 +134,7 @@ Rpl_filter::tables_ok(const char* db, TA
If there was no do list, go ahead
*/
DBUG_RETURN(some_tables_updating &&
- !do_table_inited && !wild_do_table_inited);
+ !do_table_array_inited && !wild_do_table_inited);
}
@@ -167,8 +172,13 @@ Rpl_filter::db_ok(const char* db)
while ((tmp=it++))
{
- if (!strcmp(tmp->ptr, db))
- DBUG_RETURN(1); // match
+ /*
+ Filters will follow the setting of lower_case_table_name
+ to be case sensitive when setting lower_case_table_name=0.
+ Otherwise they will be case insensitive.
+ */
+ if (!my_strcasecmp(table_alias_charset, tmp->ptr, db))
+ DBUG_RETURN(1); // match
}
DBUG_RETURN(0);
}
@@ -179,8 +189,13 @@ Rpl_filter::db_ok(const char* db)
while ((tmp=it++))
{
- if (!strcmp(tmp->ptr, db))
- DBUG_RETURN(0); // match
+ /*
+ Filters will follow the setting of lower_case_table_name
+ to be case sensitive when setting lower_case_table_name=0.
+ Otherwise they will be case insensitive.
+ */
+ if (!my_strcasecmp(table_alias_charset, tmp->ptr, db))
+ DBUG_RETURN(0); // match
}
DBUG_RETURN(1);
}
@@ -255,25 +270,25 @@ Rpl_filter::is_on()
}
-int
-Rpl_filter::add_do_table(const char* table_spec)
+int
+Rpl_filter::add_do_table_array(const char* table_spec)
{
DBUG_ENTER("Rpl_filter::add_do_table");
- if (!do_table_inited)
- init_table_rule_hash(&do_table, &do_table_inited);
+ if (!do_table_array_inited)
+ init_table_rule_array(&do_table_array, &do_table_array_inited);
table_rules_on= 1;
- DBUG_RETURN(add_table_rule(&do_table, table_spec));
+ DBUG_RETURN(add_table_rule_to_array(&do_table_array, table_spec));
}
-
-int
-Rpl_filter::add_ignore_table(const char* table_spec)
+
+int
+Rpl_filter::add_ignore_table_array(const char* table_spec)
{
DBUG_ENTER("Rpl_filter::add_ignore_table");
- if (!ignore_table_inited)
- init_table_rule_hash(&ignore_table, &ignore_table_inited);
+ if (!ignore_table_array_inited)
+ init_table_rule_array(&ignore_table_array, &ignore_table_array_inited);
table_rules_on= 1;
- DBUG_RETURN(add_table_rule(&ignore_table, table_spec));
+ DBUG_RETURN(add_table_rule_to_array(&ignore_table_array, table_spec));
}
@@ -284,7 +299,7 @@ Rpl_filter::add_wild_do_table(const char
if (!wild_do_table_inited)
init_table_rule_array(&wild_do_table, &wild_do_table_inited);
table_rules_on= 1;
- DBUG_RETURN(add_wild_table_rule(&wild_do_table, table_spec));
+ DBUG_RETURN(add_table_rule_to_array(&wild_do_table, table_spec));
}
@@ -295,7 +310,7 @@ Rpl_filter::add_wild_ignore_table(const
if (!wild_ignore_table_inited)
init_table_rule_array(&wild_ignore_table, &wild_ignore_table_inited);
table_rules_on= 1;
- DBUG_RETURN(add_wild_table_rule(&wild_ignore_table, table_spec));
+ DBUG_RETURN(add_table_rule_to_array(&wild_ignore_table, table_spec));
}
@@ -307,31 +322,137 @@ Rpl_filter::add_db_rewrite(const char* f
}
-int
-Rpl_filter::add_table_rule(HASH* h, const char* table_spec)
+/*
+ Build do_table rules to HASH from DYNAMIC_ARRAY
+ for faster filter checking.
+
+ @return
+ 0 ok
+ 1 error
+*/
+int
+Rpl_filter::build_do_table_hash()
+{
+ DBUG_ENTER("Rpl_filter::build_do_table_hash");
+
+ if (build_table_hash_from_array(&do_table_array, &do_table_hash,
+ do_table_array_inited, &do_table_hash_inited))
+ DBUG_RETURN(1);
+
+ /* Free do table ARRAY as it is a copy in do table HASH */
+ if (do_table_array_inited)
+ {
+ free_string_array(&do_table_array);
+ do_table_array_inited= FALSE;
+ }
+
+ DBUG_RETURN(0);
+}
+
+/*
+ Build ignore_table rules to HASH from DYNAMIC_ARRAY
+ for faster filter checking.
+
+ @return
+ 0 ok
+ 1 error
+*/
+int
+Rpl_filter::build_ignore_table_hash()
+{
+ DBUG_ENTER("Rpl_filter::build_ignore_table_hash");
+
+ if (build_table_hash_from_array(&ignore_table_array, &ignore_table_hash,
+ ignore_table_array_inited, &ignore_table_hash_inited))
+ DBUG_RETURN(1);
+
+ /* Free ignore table ARRAY as it is a copy in ignore table HASH */
+ if (ignore_table_array_inited)
+ {
+ free_string_array(&ignore_table_array);
+ ignore_table_array_inited= FALSE;
+ }
+
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Table rules are initially added to DYNAMIC_LIST, and then,
+ when the charset to use for tables has been established,
+ inserted into a HASH for faster filter checking.
+
+ @param[in] table_array DYNAMIC_ARRAY stored table rules
+ @param[in] table_hash HASH for storing table rules
+ @param[in] array_inited Table rules are added to DYNAMIC_ARRAY
+ @param[in] hash_inited Table rules are added to HASH
+
+ @return
+ 0 ok
+ 1 error
+*/
+int
+Rpl_filter::build_table_hash_from_array(DYNAMIC_ARRAY *table_array, HASH *table_hash,
+ bool array_inited, bool *hash_inited)
+{
+ DBUG_ENTER("Rpl_filter::build_table_hash");
+
+ if (array_inited)
+ {
+ init_table_rule_hash(table_hash, hash_inited);
+ for (uint i= 0; i < table_array->elements; i++)
+ {
+ TABLE_RULE_ENT* e;
+ get_dynamic(table_array, (uchar*)&e, i);
+ if (add_table_rule_to_hash(table_hash, e->db, e->key_len))
+ DBUG_RETURN(1);
+ }
+ }
+
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Added one table rule to HASH.
+
+ @param[in] h HASH for storing table rules
+ @param[in] table_spec Table name with db
+ @param[in] len The length of table_spec
+
+ @return
+ 0 ok
+ 1 error
+*/
+int
+Rpl_filter::add_table_rule_to_hash(HASH* h, const char* table_spec, uint len)
{
const char* dot = strchr(table_spec, '.');
if (!dot) return 1;
// len is always > 0 because we know the there exists a '.'
- uint len = (uint)strlen(table_spec);
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
- + len, MYF(MY_WME));
+ + len, MYF(MY_WME));
if (!e) return 1;
e->db= (char*)e + sizeof(TABLE_RULE_ENT);
e->tbl_name= e->db + (dot - table_spec) + 1;
e->key_len= len;
memcpy(e->db, table_spec, len);
- return my_hash_insert(h, (uchar*)e);
+ if (my_hash_insert(h, (uchar*)e))
+ {
+ my_free(e);
+ return 1;
+ }
+ return 0;
}
/*
- Add table expression with wildcards to dynamic array
+ Add table expression to dynamic array
*/
-int
-Rpl_filter::add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
+int
+Rpl_filter::add_table_rule_to_array(DYNAMIC_ARRAY* a, const char* table_spec)
{
const char* dot = strchr(table_spec, '.');
if (!dot) return 1;
@@ -343,7 +464,13 @@ Rpl_filter::add_wild_table_rule(DYNAMIC_
e->tbl_name= e->db + (dot - table_spec) + 1;
e->key_len= len;
memcpy(e->db, table_spec, len);
- return insert_dynamic(a, (uchar*)&e);
+
+ if (insert_dynamic(a, (uchar*)&e))
+ {
+ my_free(e);
+ return 1;
+ }
+ return 0;
}
@@ -387,11 +514,11 @@ void free_table_ent(void* a)
}
-void
+void
Rpl_filter::init_table_rule_hash(HASH* h, bool* h_inited)
{
- my_hash_init(h, system_charset_info,TABLE_RULE_HASH_SIZE,0,0,
- get_table_key, free_table_ent, 0);
+ my_hash_init(h, table_alias_charset, TABLE_RULE_HASH_SIZE,0,0,
+ get_table_key, free_table_ent, 0);
*h_inited = 1;
}
@@ -410,12 +537,17 @@ Rpl_filter::find_wild(DYNAMIC_ARRAY *a,
{
uint i;
const char* key_end= key + len;
-
+
for (i= 0; i < a->elements; i++)
{
TABLE_RULE_ENT* e ;
get_dynamic(a, (uchar*)&e, i);
- if (!my_wildcmp(system_charset_info, key, key_end,
+ /*
+ Filters will follow the setting of lower_case_table_name
+ to be case sensitive when setting lower_case_table_name=0.
+ Otherwise they will be case insensitive.
+ */
+ if (!my_wildcmp(table_alias_charset, key, key_end,
(const char*)e->db,
(const char*)(e->db + e->key_len),
'\\',wild_one,wild_many))
@@ -492,14 +624,14 @@ Rpl_filter::table_rule_ent_dynamic_array
void
Rpl_filter::get_do_table(String* str)
{
- table_rule_ent_hash_to_str(str, &do_table, do_table_inited);
+ table_rule_ent_hash_to_str(str, &do_table_hash, do_table_hash_inited);
}
void
Rpl_filter::get_ignore_table(String* str)
{
- table_rule_ent_hash_to_str(str, &ignore_table, ignore_table_inited);
+ table_rule_ent_hash_to_str(str, &ignore_table_hash, ignore_table_hash_inited);
}
@@ -527,7 +659,12 @@ Rpl_filter::get_rewrite_db(const char* d
while ((tmp=it++))
{
- if (!strcmp(tmp->key, db))
+ /*
+ Filters will follow the setting of lower_case_table_name
+ to be case sensitive when setting lower_case_table_name=0.
+ Otherwise they will be case insensitive.
+ */
+ if (!my_strcasecmp(table_alias_charset, tmp->key, db))
{
*new_len= strlen(tmp->val);
return tmp->val;
=== modified file 'sql/rpl_filter.h'
--- a/sql/rpl_filter.h 2010-07-02 18:15:21 +0000
+++ b/sql/rpl_filter.h 2010-09-15 07:31:48 +0000
@@ -55,9 +55,11 @@ public:
bool is_on();
/* Setters - add filtering rules */
+ int build_do_table_hash();
+ int build_ignore_table_hash();
- int add_do_table(const char* table_spec);
- int add_ignore_table(const char* table_spec);
+ int add_do_table_array(const char* table_spec);
+ int add_ignore_table_array(const char* table_spec);
int add_wild_do_table(const char* table_spec);
int add_wild_ignore_table(const char* table_spec);
@@ -86,8 +88,8 @@ private:
void init_table_rule_hash(HASH* h, bool* h_inited);
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
- int add_table_rule(HASH* h, const char* table_spec);
- int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
+ int add_table_rule_to_array(DYNAMIC_ARRAY* a, const char* table_spec);
+ int add_table_rule_to_hash(HASH* h, const char* table_spec, uint len);
void free_string_array(DYNAMIC_ARRAY *a);
@@ -96,17 +98,27 @@ private:
bool inited);
TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len);
+ int build_table_hash_from_array(DYNAMIC_ARRAY *table_array, HASH *table_hash,
+ bool array_inited, bool *hash_inited);
+
/*
- Those 4 structures below are uninitialized memory unless the
+ Those 6 structures below are uninitialized memory unless the
corresponding *_inited variables are "true".
*/
- HASH do_table;
- HASH ignore_table;
+ /* For quick search */
+ HASH do_table_hash;
+ HASH ignore_table_hash;
+
+ DYNAMIC_ARRAY do_table_array;
+ DYNAMIC_ARRAY ignore_table_array;
+
DYNAMIC_ARRAY wild_do_table;
DYNAMIC_ARRAY wild_ignore_table;
- bool do_table_inited;
- bool ignore_table_inited;
+ bool do_table_hash_inited;
+ bool ignore_table_hash_inited;
+ bool do_table_array_inited;
+ bool ignore_table_array_inited;
bool wild_do_table_inited;
bool wild_ignore_table_inited;
=== modified file 'strings/ctype-utf8.c'
--- a/strings/ctype-utf8.c 2010-09-01 06:35:04 +0000
+++ b/strings/ctype-utf8.c 2010-09-15 07:31:48 +0000
@@ -4652,13 +4652,15 @@ MY_UNICASE_INFO my_unicase_unicode520=
static inline void
-my_tosort_unicode(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
+my_tosort_unicode(MY_UNICASE_INFO *uni_plane, my_wc_t *wc, uint flags)
{
if (*wc <= uni_plane->maxchar)
{
MY_UNICASE_CHARACTER *page;
if ((page= uni_plane->page[*wc >> 8]))
- *wc= page[*wc & 0xFF].sort;
+ *wc= (flags & MY_CS_LOWER_SORT) ?
+ page[*wc & 0xFF].tolower :
+ page[*wc & 0xFF].sort;
}
else
{
@@ -4728,8 +4730,8 @@ my_wildcmp_unicode(CHARSET_INFO *cs,
{
if (weights)
{
- my_tosort_unicode(weights, &s_wc);
- my_tosort_unicode(weights, &w_wc);
+ my_tosort_unicode(weights, &s_wc, cs->state);
+ my_tosort_unicode(weights, &w_wc, cs->state);
}
if (s_wc != w_wc)
return 1; /* No match */
@@ -4799,8 +4801,8 @@ my_wildcmp_unicode(CHARSET_INFO *cs,
return 1;
if (weights)
{
- my_tosort_unicode(weights, &s_wc);
- my_tosort_unicode(weights, &w_wc);
+ my_tosort_unicode(weights, &s_wc, cs->state);
+ my_tosort_unicode(weights, &w_wc, cs->state);
}
if (s_wc == w_wc)
@@ -4917,7 +4919,7 @@ my_strnxfrm_unicode(CHARSET_INFO *cs,
src+= res;
if (uni_plane)
- my_tosort_unicode(uni_plane, &wc);
+ my_tosort_unicode(uni_plane, &wc, cs->state);
*dst++= (uchar) (wc >> 8);
if (dst < de)
@@ -5390,7 +5392,7 @@ static void my_hash_sort_utf8(CHARSET_IN
while ((s < e) && (res=my_utf8_uni(cs,&wc, (uchar *)s, (uchar*)e))>0 )
{
- my_tosort_unicode(uni_plane, &wc);
+ my_tosort_unicode(uni_plane, &wc, cs->state);
n1[0]^= (((n1[0] & 63)+n2[0])*(wc & 0xFF))+ (n1[0] << 8);
n2[0]+=3;
n1[0]^= (((n1[0] & 63)+n2[0])*(wc >> 8))+ (n1[0] << 8);
@@ -5504,8 +5506,8 @@ static int my_strnncoll_utf8(CHARSET_INF
return bincmp(s, se, t, te);
}
- my_tosort_unicode(uni_plane, &s_wc);
- my_tosort_unicode(uni_plane, &t_wc);
+ my_tosort_unicode(uni_plane, &s_wc, cs->state);
+ my_tosort_unicode(uni_plane, &t_wc, cs->state);
if ( s_wc != t_wc )
{
@@ -5575,8 +5577,8 @@ static int my_strnncollsp_utf8(CHARSET_I
return bincmp(s, se, t, te);
}
- my_tosort_unicode(uni_plane, &s_wc);
- my_tosort_unicode(uni_plane, &t_wc);
+ my_tosort_unicode(uni_plane, &s_wc, cs->state);
+ my_tosort_unicode(uni_plane, &t_wc, cs->state);
if ( s_wc != t_wc )
{
@@ -5868,6 +5870,40 @@ CHARSET_INFO my_charset_utf8_general_ci=
};
+CHARSET_INFO my_charset_utf8_tolower_ci=
+{
+ 56,0,0, /* number */
+ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_LOWER_SORT,
+ "utf8", /* cs name */
+ "utf8_tolower_ci", /* name */
+ "", /* comment */
+ NULL, /* tailoring */
+ ctype_utf8, /* ctype */
+ to_lower_utf8, /* to_lower */
+ to_upper_utf8, /* to_upper */
+ to_upper_utf8, /* sort_order */
+ NULL, /* uca */
+ NULL, /* tab_to_uni */
+ NULL, /* tab_from_uni */
+ &my_unicase_default,/* caseinfo */
+ NULL, /* state_map */
+ NULL, /* ident_map */
+ 1, /* strxfrm_multiply */
+ 1, /* caseup_multiply */
+ 1, /* casedn_multiply */
+ 1, /* mbminlen */
+ 3, /* mbmaxlen */
+ 0, /* min_sort_char */
+ 0xFFFF, /* max_sort_char */
+ ' ', /* pad char */
+ 0, /* escape_with_backslash_is_dangerous */
+ 1, /* levels_for_compare */
+ 1, /* levels_for_order */
+ &my_charset_utf8_handler,
+ &my_collation_utf8_general_ci_handler
+};
+
+
CHARSET_INFO my_charset_utf8_bin=
{
83,0,0, /* number */
@@ -5939,10 +5975,10 @@ static int my_strnncoll_utf8_cs(CHARSET_
{
save_diff = ((int)s_wc) - ((int)t_wc);
}
-
- my_tosort_unicode(uni_plane, &s_wc);
- my_tosort_unicode(uni_plane, &t_wc);
-
+
+ my_tosort_unicode(uni_plane, &s_wc, cs->state);
+ my_tosort_unicode(uni_plane, &t_wc, cs->state);
+
if ( s_wc != t_wc )
{
return ((int) s_wc) - ((int) t_wc);
@@ -5986,10 +6022,10 @@ static int my_strnncollsp_utf8_cs(CHARSE
{
save_diff = ((int)s_wc) - ((int)t_wc);
}
-
- my_tosort_unicode(uni_plane, &s_wc);
- my_tosort_unicode(uni_plane, &t_wc);
-
+
+ my_tosort_unicode(uni_plane, &s_wc, cs->state);
+ my_tosort_unicode(uni_plane, &t_wc, cs->state);
+
if ( s_wc != t_wc )
{
return ((int) s_wc) - ((int) t_wc);
@@ -7798,7 +7834,7 @@ my_hash_sort_utf8mb4(CHARSET_INFO *cs, c
while ((res= my_mb_wc_utf8mb4(cs, &wc, (uchar*) s, (uchar*) e)) > 0)
{
- my_tosort_unicode(uni_plane, &wc);
+ my_tosort_unicode(uni_plane, &wc, cs->state);
my_hash_add(n1, n2, (uint) (wc & 0xFF));
my_hash_add(n1, n2, (uint) (wc >> 8) & 0xFF);
if (wc > 0xFFFF)
@@ -7928,9 +7964,9 @@ my_strnncoll_utf8mb4(CHARSET_INFO *cs,
return bincmp_utf8mb4(s, se, t, te);
}
- my_tosort_unicode(uni_plane, &s_wc);
- my_tosort_unicode(uni_plane, &t_wc);
-
+ my_tosort_unicode(uni_plane, &s_wc, cs->state);
+ my_tosort_unicode(uni_plane, &t_wc, cs->state);
+
if ( s_wc != t_wc )
{
return s_wc > t_wc ? 1 : -1;
@@ -7999,8 +8035,8 @@ my_strnncollsp_utf8mb4(CHARSET_INFO *cs,
return bincmp_utf8mb4(s, se, t, te);
}
- my_tosort_unicode(uni_plane, &s_wc);
- my_tosort_unicode(uni_plane, &t_wc);
+ my_tosort_unicode(uni_plane, &s_wc, cs->state);
+ my_tosort_unicode(uni_plane, &t_wc, cs->state);
if ( s_wc != t_wc )
{
Attachment: [text/bzr-bundle] bzr/dao-gang.qu@sun.com-20100915073148-f2ohp8h9moyv2xmv.bundle
Thread |
---|
• bzr commit into mysql-next-mr-bugfixing branch (Dao-Gang.Qu:3287) Bug#51639 | Dao-Gang.Qu | 15 Sep |