diff options
author | unknown <aelkin@mysql.com> | 2006-01-23 18:03:09 +0200 |
---|---|---|
committer | unknown <aelkin@mysql.com> | 2006-01-23 18:03:09 +0200 |
commit | 1dcfe028a7e5509489cf2db5db37c3e2c6705d76 (patch) | |
tree | ede7ea9a78393a073eebd7b62ff0ff3ad03049a3 | |
parent | 2bdcc1714e2c84e5d4dcd21ad27c459d3a7b79b6 (diff) | |
download | mariadb-git-1dcfe028a7e5509489cf2db5db37c3e2c6705d76.tar.gz |
BUG#15699, failure to apply ignore rule for unexisting table.
Since replication rules execute after `mysql_multi_update_prepare' returns we
delay to `break' in case this functions returns non-zero (some tables are not found)
for to examine if there is an ignore rule for a not-found table. By doing that
it is guaranteed do/ignore replication rules logically preceed opening table routine.
sql/sql_parse.cc:
BUG#15699. We delay to `break' in case of unexisted tables for multi-update.
First it is checked whether an ignore rule for such a table exists.
More to the fix:
if (opt_readonly && ...' in two places got be idented because it were
enclosed explicitly into corresponding `else' groups. For that
the preceding lines with `else' were changed in to be
`else
{'.
This grouping is necessary to avoid any inattentive
insertion in between of `else' and belonging to the else
`if (opt_readonly && ...' statement.
mysql-test/r/rpl_multi_update4.result:
New BitKeeper file ``mysql-test/r/rpl_multi_update4.result''
mysql-test/t/rpl_multi_update4-slave.opt:
New BitKeeper file ``mysql-test/t/rpl_multi_update4-slave.opt''
mysql-test/t/rpl_multi_update4.test:
New BitKeeper file ``mysql-test/t/rpl_multi_update4.test''
-rw-r--r-- | mysql-test/r/rpl_multi_update4.result | 25 | ||||
-rw-r--r-- | mysql-test/t/rpl_multi_update4-slave.opt | 1 | ||||
-rw-r--r-- | mysql-test/t/rpl_multi_update4.test | 44 | ||||
-rw-r--r-- | sql/sql_parse.cc | 65 |
4 files changed, 110 insertions, 25 deletions
diff --git a/mysql-test/r/rpl_multi_update4.result b/mysql-test/r/rpl_multi_update4.result new file mode 100644 index 00000000000..f6dde65a35d --- /dev/null +++ b/mysql-test/r/rpl_multi_update4.result @@ -0,0 +1,25 @@ +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; +drop database if exists d1; +drop database if exists d2; +drop database if exists d2; +create database d1; +create table d1.t0 (id int); +create database d2; +use d2; +create table t1 (id int); +create table t2 (id int); +insert into t1 values (1), (2), (3), (4), (5); +insert into t2 select id + 3 from t1; +update t1 join t2 using (id) set t1.id = 0; +insert into d1.t0 values (0); +use d1; +select * from t0 where id=0; +id +0 +drop database d1; +drop database d2; diff --git a/mysql-test/t/rpl_multi_update4-slave.opt b/mysql-test/t/rpl_multi_update4-slave.opt new file mode 100644 index 00000000000..fea27db43ee --- /dev/null +++ b/mysql-test/t/rpl_multi_update4-slave.opt @@ -0,0 +1 @@ +--replicate-wild-do-table=d1.% diff --git a/mysql-test/t/rpl_multi_update4.test b/mysql-test/t/rpl_multi_update4.test new file mode 100644 index 00000000000..3d909b8e5cd --- /dev/null +++ b/mysql-test/t/rpl_multi_update4.test @@ -0,0 +1,44 @@ +# Let's verify that multi-update is not always skipped by slave if +# some replicate-* rules exist. +# (BUG#15699) + +source include/master-slave.inc; + +### Clean-up + +connection master; +--disable_warnings +drop database if exists d1; +drop database if exists d2; + +connection slave; +drop database if exists d2; +--enable_warnings + +### Test + +connection master; +create database d1; # accepted by slave +create table d1.t0 (id int); +create database d2; # ignored by slave +use d2; +create table t1 (id int); +create table t2 (id int); +insert into t1 values (1), (2), (3), (4), (5); +insert into t2 select id + 3 from t1; +# a problematic query which must be filter out by slave +update t1 join t2 using (id) set t1.id = 0; +insert into d1.t0 values (0); # replication works + +sync_slave_with_master; +use d1; +#connection slave; +select * from t0 where id=0; # must find + +### Clean-up +connection master; +drop database d1; +drop database d2; + + +# End of test diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index df366643cf9..1cbc616f63f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2415,23 +2415,26 @@ mysql_execute_command(THD *thd) } } else + { #endif /* HAVE_REPLICATION */ - - /* - When option readonly is set deny operations which change non-temporary - tables. Except for the replication thread and the 'super' users. - */ - if (opt_readonly && - !(thd->security_ctx->master_access & SUPER_ACL) && - uc_update_queries[lex->sql_command] && - !((lex->sql_command == SQLCOM_CREATE_TABLE) && - (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) && - ((lex->sql_command != SQLCOM_UPDATE_MULTI) && - some_non_temp_table_to_be_updated(thd, all_tables))) - { - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); - DBUG_RETURN(-1); - } + /* + When option readonly is set deny operations which change non-temporary + tables. Except for the replication thread and the 'super' users. + */ + if (opt_readonly && + !(thd->security_ctx->master_access & SUPER_ACL) && + uc_update_queries[lex->sql_command] && + !((lex->sql_command == SQLCOM_CREATE_TABLE) && + (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) && + ((lex->sql_command != SQLCOM_UPDATE_MULTI) && + some_non_temp_table_to_be_updated(thd, all_tables))) + { + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); + DBUG_RETURN(-1); + } +#ifdef HAVE_REPLICATION + } /* endif unlikely slave */ +#endif if(lex->orig_sql_command == SQLCOM_END) statistic_increment(thd->status_var.com_stat[lex->sql_command], &LOCK_status); @@ -3232,8 +3235,7 @@ end_with_restore_list: else res= 0; - if ((res= mysql_multi_update_prepare(thd))) - break; + res= mysql_multi_update_prepare(thd); #ifdef HAVE_REPLICATION /* Check slave filtering rules */ @@ -3241,20 +3243,33 @@ end_with_restore_list: { if (all_tables_not_ok(thd, all_tables)) { + if (res!= 0) + { + res= 0; /* don't care of prev failure */ + thd->clear_error(); /* filters are of highest prior */ + } /* we warn the slave SQL thread */ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); break; } + if (res) + break; } else -#endif /* HAVE_REPLICATION */ - if (opt_readonly && - !(thd->security_ctx->master_access & SUPER_ACL) && - some_non_temp_table_to_be_updated(thd, all_tables)) { - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); - break; - } +#endif /* HAVE_REPLICATION */ + if (res) + break; + if (opt_readonly && + !(thd->security_ctx->master_access & SUPER_ACL) && + some_non_temp_table_to_be_updated(thd, all_tables)) + { + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); + break; + } +#ifdef HAVE_REPLICATION + } /* unlikely */ +#endif res= mysql_multi_update(thd, all_tables, &select_lex->item_list, |