summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/federated.result38
-rw-r--r--mysql-test/t/federated.test57
-rw-r--r--sql/ha_federated.cc89
3 files changed, 118 insertions, 66 deletions
diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result
index 2eb0c81ec2e..cf75a013572 100644
--- a/mysql-test/r/federated.result
+++ b/mysql-test/r/federated.result
@@ -1689,6 +1689,44 @@ id c1 c2
9 abc ppc
drop table federated.t1, federated.t2;
drop table federated.t1, federated.t2;
+DROP TABLE IF EXISTS federated.test;
+CREATE TABLE federated.test (
+`id` int(11) NOT NULL,
+`val1` varchar(255) NOT NULL,
+`val2` varchar(255) NOT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+DROP TABLE IF EXISTS federated.test_local;
+DROP TABLE IF EXISTS federated.test_remote;
+CREATE TABLE federated.test_local (
+`id` int(11) NOT NULL,
+`val1` varchar(255) NOT NULL,
+`val2` varchar(255) NOT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO federated.test_local VALUES (1, 'foo', 'bar'),
+(2, 'bar', 'foo');
+CREATE TABLE federated.test_remote (
+`id` int(11) NOT NULL,
+`val1` varchar(255) NOT NULL,
+`val2` varchar(255) NOT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=FEDERATED DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/test';
+insert into federated.test_remote select * from federated.test_local;
+select * from federated.test_remote;
+id val1 val2
+1 foo bar
+2 bar foo
+delete from federated.test_remote where id in (1,2);
+insert into federated.test_remote select * from federated.test_local;
+select * from federated.test_remote;
+id val1 val2
+2 bar foo
+1 foo bar
+DROP TABLE federated.test_local;
+DROP TABLE federated.test_remote;
+DROP TABLE federated.test;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1;
diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test
index a8b16edc80a..d6efb870e55 100644
--- a/mysql-test/t/federated.test
+++ b/mysql-test/t/federated.test
@@ -1365,4 +1365,61 @@ drop table federated.t1, federated.t2;
connection slave;
drop table federated.t1, federated.t2;
+#
+# BUG #18764: Delete conditions causing inconsistencies in Federated tables
+#
+connection slave;
+--disable_warnings
+DROP TABLE IF EXISTS federated.test;
+--enable_warnings
+CREATE TABLE federated.test (
+ `id` int(11) NOT NULL,
+ `val1` varchar(255) NOT NULL,
+ `val2` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+connection master;
+--disable_warnings
+DROP TABLE IF EXISTS federated.test_local;
+DROP TABLE IF EXISTS federated.test_remote;
+--enable_warnings
+CREATE TABLE federated.test_local (
+ `id` int(11) NOT NULL,
+ `val1` varchar(255) NOT NULL,
+ `val2` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+INSERT INTO federated.test_local VALUES (1, 'foo', 'bar'),
+(2, 'bar', 'foo');
+
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE federated.test_remote (
+ `id` int(11) NOT NULL,
+ `val1` varchar(255) NOT NULL,
+ `val2` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=FEDERATED DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/test';
+
+insert into federated.test_remote select * from federated.test_local;
+
+select * from federated.test_remote;
+
+delete from federated.test_remote where id in (1,2);
+
+insert into federated.test_remote select * from federated.test_local;
+
+select * from federated.test_remote;
+--disable_warnings
+DROP TABLE federated.test_local;
+DROP TABLE federated.test_remote;
+--enable_warnings
+
+connection slave;
+--disable_warnings
+DROP TABLE federated.test;
+--enable_warnings
+
source include/federated_cleanup.inc;
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index 11f676d9cf6..abdcb6dc9c0 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -1559,10 +1559,6 @@ inline uint field_in_record_is_null(TABLE *table,
int ha_federated::write_row(byte *buf)
{
- bool has_fields= FALSE;
- uint all_fields_have_same_query_id= 1;
- ulong current_query_id= 1;
- ulong tmp_query_id= 1;
char insert_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char values_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char insert_field_value_buffer[STRING_BUFFER_USUAL_SIZE];
@@ -1580,24 +1576,12 @@ int ha_federated::write_row(byte *buf)
insert_string.length(0);
insert_field_value_string.length(0);
DBUG_ENTER("ha_federated::write_row");
- DBUG_PRINT("info",
- ("table charset name %s csname %s",
- table->s->table_charset->name,
- table->s->table_charset->csname));
statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
/*
- get the current query id - the fields that we add to the insert
- statement to send to the foreign will not be appended unless they match
- this query id
- */
- current_query_id= table->in_use->query_id;
- DBUG_PRINT("info", ("current query id %d", current_query_id));
-
- /*
start both our field and field values strings
*/
insert_string.append(FEDERATED_INSERT);
@@ -1610,63 +1594,36 @@ int ha_federated::write_row(byte *buf)
values_string.append(FEDERATED_OPENPAREN);
/*
- Even if one field is different, all_fields_same_query_id can't remain
- 0 if it remains 0, then that means no fields were specified in the query
- such as in the case of INSERT INTO table VALUES (val1, val2, valN)
-
- */
- for (field= table->field; *field; field++)
- {
- if (field > table->field && tmp_query_id != (*field)->query_id)
- all_fields_have_same_query_id= 0;
-
- tmp_query_id= (*field)->query_id;
- }
- /*
loop through the field pointer array, add any fields to both the values
list and the fields list that match the current query id
-
- You might ask "Why an index variable (has_fields) ?" My answer is that
- we need to count how many fields we actually need
*/
for (field= table->field; *field; field++)
{
- /* if there is a query id and if it's equal to the current query id */
- if (((*field)->query_id && (*field)->query_id == current_query_id)
- || all_fields_have_same_query_id)
+ if ((*field)->is_null())
+ insert_field_value_string.append(FEDERATED_NULL);
+ else
{
- /*
- There are some fields. This will be used later to determine
- whether to chop off commas and parens.
- */
- has_fields= TRUE;
-
- if ((*field)->is_null())
- insert_field_value_string.append(FEDERATED_NULL);
- else
- {
- (*field)->val_str(&insert_field_value_string);
- /* quote these fields if they require it */
- (*field)->quote_data(&insert_field_value_string);
- }
- /* append the field name */
- insert_string.append((*field)->field_name);
+ (*field)->val_str(&insert_field_value_string);
+ /* quote these fields if they require it */
+ (*field)->quote_data(&insert_field_value_string);
+ }
+ /* append the field name */
+ insert_string.append((*field)->field_name);
- /* append the value */
- values_string.append(insert_field_value_string);
- insert_field_value_string.length(0);
+ /* append the value */
+ values_string.append(insert_field_value_string);
+ insert_field_value_string.length(0);
- /* append commas between both fields and fieldnames */
- /*
- unfortunately, we can't use the logic
- if *(fields + 1) to make the following
- appends conditional because we may not append
- if the next field doesn't match the condition:
- (((*field)->query_id && (*field)->query_id == current_query_id)
- */
- insert_string.append(FEDERATED_COMMA);
- values_string.append(FEDERATED_COMMA);
- }
+ /* append commas between both fields and fieldnames */
+ /*
+ unfortunately, we can't use the logic
+ if *(fields + 1) to make the following
+ appends conditional because we may not append
+ if the next field doesn't match the condition:
+ (((*field)->query_id && (*field)->query_id == current_query_id)
+ */
+ insert_string.append(FEDERATED_COMMA);
+ values_string.append(FEDERATED_COMMA);
}
/*
@@ -1678,7 +1635,7 @@ int ha_federated::write_row(byte *buf)
AND, we don't want to chop off the last char '('
insert will be "INSERT INTO t1 VALUES ();"
*/
- if (has_fields)
+ if (table->s->fields)
{
/* chops off leading commas */
values_string.length(values_string.length() - strlen(FEDERATED_COMMA));