Description:
INSERT ... SELECT ... ON DUPLICATE KEY UPDATE doesn't seem to work with federated tables, while REPLACE ... SELECT ... works as expected.
How to repeat:
Create the same table in database test and remote_test (used to simulate a remote mysql server)
USE test;
DROP TABLE IF EXISTS `test`.`catalogue`;
CREATE TABLE `test`.`catalogue` (
`product_code` char(10) NOT NULL,
`product_name` varchar(45) DEFAULT NULL,
`product_desc` varchar(500) DEFAULT NULL,
`product_weight` decimal(10,0) DEFAULT NULL,
`product_colour` varchar(45) DEFAULT NULL,
PRIMARY KEY (`product_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE DATABASE `remote_test`;
DROP TABLE IF EXISTS `remote_test`.`catalogue`;
CREATE TABLE `remote_test`.`catalogue` (
`product_code` char(10) NOT NULL,
`product_name` varchar(45) DEFAULT NULL,
`product_desc` varchar(500) DEFAULT NULL,
`product_weight` decimal(10,0) DEFAULT NULL,
`product_colour` varchar(45) DEFAULT NULL,
PRIMARY KEY (`product_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Now create a federated table in test database pointng to catalogue table in remote_test database
DROP TABLE IF EXISTS `test`.`remote_catalogue`;
CREATE TABLE `test`.`remote_catalogue` (
`product_code` char(10) NOT NULL,
`product_name` varchar(45) NOT NULL,
`product_desc` varchar(500) NOT NULL,
`product_weight` decimal(10,0) NOT NULL,
`product_colour` varchar(45) NOT NULL,
PRIMARY KEY (`product_code`)
) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root:nt300jk@127.0.0.1:3306/remote_test/catalogue';
Now insert a row in test.catalogue
mysql> INSERT INTO
-> catalogue
-> VALUES
-> ('AB12G', 'Lg. Widget', 'A large widget', 34, 'blue');
Query OK, 1 row affected (0.00 sec)
Now perform a fist sync using
mysql> INSERT INTO
-> remote_catalogue
-> (product_code, product_name, product_desc, product_weight, product_colo
ur)
-> SELECT
-> *
-> FROM
-> catalogue
-> ON DUPLICATE KEY UPDATE
-> product_code = VALUES(product_code),
-> product_name = VALUES(product_name),
-> product_desc = VALUES(product_desc),
-> product_weight = VALUES(product_weight),
-> product_colour = VALUES(product_colour);
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
Check on the other side:
mysql> select * from catalogue;
+--------------+--------------+----------------+----------------+---------------
-+
| product_code | product_name | product_desc | product_weight | product_colour
|
+--------------+--------------+----------------+----------------+---------------
-+
| AB12G | Lg. Widget | A large widget | 34 | blue
|
+--------------+--------------+----------------+----------------+---------------
-+
1 row in set (0.00 sec)
Now issue an update on test.catalogue
mysql> update test.catalogue set product_weight = 33 where product_code = 'AB12G
';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
Now attempt another sync
mysql> INSERT INTO
-> remote_catalogue
-> (product_code, product_name, product_desc, product_weight, product_colo
ur)
-> SELECT
-> *
-> FROM
-> catalogue
-> ON DUPLICATE KEY UPDATE
-> product_code = VALUES(product_code),
-> product_name = VALUES(product_name),
-> product_desc = VALUES(product_desc),
-> product_weight = VALUES(product_weight),
-> product_colour = VALUES(product_colour);
ERROR 1022 (23000): Can't write; duplicate key in table 'remote_catalogue'
This shouln't happen and the row should get updated!
A sync using REPLACE works, see
mysql> replace into remote_catalogue select * from catalogue;
Query OK, 1 row affected (0.03 sec)
Records: 1 Duplicates: 0 Warnings: 0
And on the remote site:
mysql> select * from catalogue;
+--------------+--------------+----------------+----------------+---------------
-+
| product_code | product_name | product_desc | product_weight | product_colour
|
+--------------+--------------+----------------+----------------+---------------
-+
| AB12G | Lg. Widget | A large widget | 33 | blue
|
+--------------+--------------+----------------+----------------+---------------
-+
1 row in set (0.00 sec)