Commit a1c2dc5e authored by jimw@mysql.com's avatar jimw@mysql.com

Bug #16494: Updates that set a column to NULL fail sometimes

 When building the UPDATE query to send to the remote server, the
 federated storage engine built the query incorrectly if it was updating
 a field to be NULL.

 Thanks to Bjšrn Steinbrink for an initial patch for the problem.
parent 8f4582db
......@@ -1601,6 +1601,22 @@ fld_cid fld_name fld_parentid fld_delt
5 Torkel 0 0
DROP TABLE federated.t1;
DROP TABLE federated.bug_17377_table;
create table t1 (id int not null auto_increment primary key, val int);
create table t1
(id int not null auto_increment primary key, val int) engine=federated
connection='mysql://root@127.0.0.1:9308/test/t1';
insert into t1 values (1,0),(2,0);
update t1 set val = NULL where id = 1;
select * from t1;
id val
1 NULL
2 0
select * from t1;
id val
1 NULL
2 0
drop table t1;
drop table t1;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1;
......
......@@ -1309,5 +1309,22 @@ DROP TABLE federated.t1;
connection slave;
DROP TABLE federated.bug_17377_table;
#
# Bug #16494: Updates that set a column to NULL fail sometimes
#
connection slave;
create table t1 (id int not null auto_increment primary key, val int);
connection master;
eval create table t1
(id int not null auto_increment primary key, val int) engine=federated
connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
insert into t1 values (1,0),(2,0);
update t1 set val = NULL where id = 1;
select * from t1;
connection slave;
select * from t1;
drop table t1;
connection master;
drop table t1;
source include/federated_cleanup.inc;
......@@ -1857,8 +1857,8 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
In this loop, we want to match column names to values being inserted
(while building INSERT statement).
Iterate through table->field (new data) and share->old_filed (old_data)
using the same index to created an SQL UPDATE statement, new data is
Iterate through table->field (new data) and share->old_field (old_data)
using the same index to create an SQL UPDATE statement. New data is
used to create SET field=value and old data is used to create WHERE
field=oldvalue
*/
......@@ -1870,30 +1870,28 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
update_string.append(FEDERATED_EQ);
if ((*field)->is_null())
new_field_value.append(FEDERATED_NULL);
update_string.append(FEDERATED_NULL);
else
{
/* otherwise = */
(*field)->val_str(&new_field_value);
(*field)->quote_data(&new_field_value);
if (!field_in_record_is_null(table, *field, (char*) old_data))
where_string.append(FEDERATED_EQ);
update_string.append(new_field_value);
new_field_value.length(0);
}
if (field_in_record_is_null(table, *field, (char*) old_data))
where_string.append(FEDERATED_ISNULL);
else
{
where_string.append(FEDERATED_EQ);
(*field)->val_str(&old_field_value,
(char*) (old_data + (*field)->offset()));
(*field)->quote_data(&old_field_value);
where_string.append(old_field_value);
old_field_value.length(0);
}
update_string.append(new_field_value);
new_field_value.length(0);
/*
Only append conjunctions if we have another field in which
to iterate
......@@ -1903,7 +1901,6 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
update_string.append(FEDERATED_COMMA);
where_string.append(FEDERATED_AND);
}
old_field_value.length(0);
}
update_string.append(FEDERATED_WHERE);
update_string.append(where_string);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment