summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <aelkin@mysql.com>2006-01-23 18:03:09 +0200
committerunknown <aelkin@mysql.com>2006-01-23 18:03:09 +0200
commit1dcfe028a7e5509489cf2db5db37c3e2c6705d76 (patch)
treeede7ea9a78393a073eebd7b62ff0ff3ad03049a3
parent2bdcc1714e2c84e5d4dcd21ad27c459d3a7b79b6 (diff)
downloadmariadb-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.result25
-rw-r--r--mysql-test/t/rpl_multi_update4-slave.opt1
-rw-r--r--mysql-test/t/rpl_multi_update4.test44
-rw-r--r--sql/sql_parse.cc65
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,