From c18896f9c1ce6e4b9a8519a2d5155698d82ae45a Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 27 Dec 2021 18:51:00 +0200 Subject: MDEV-14907 FEDERATEDX doesn't respect DISTINCT Federated and Federatex cannot be used with ROR scans Federated::position() and Federatex::position() is storing in 'ref' a pointer into a local result set buffer. This means that one cannot compare 'ref' from different handler instances to see if they point to the same physical record. This bug caused federated.federatedx to return wrong results when the optimizer tried to use index_merge to resolve some queries. Fixed by introducing table flag HA_NON_COMPARABLE_ROWID and using this with the above handlers. Todo: - Fix multi_delete(), multi_update and read_records() to use primary key instead of 'ref' if case HA_NON_COMPARABLE_ROWID is set. The current code only works if we have only one range (like table scan) for the tables that will be updated in the second pass. - Enable DBUG_ASSERT() in ha_federated::cmp_ref() and ha_federatedx::cmp_ref(). --- mysql-test/suite/federated/optimizer.result | 52 +++++++++++++++++++++++++++++ mysql-test/suite/federated/optimizer.test | 39 ++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 mysql-test/suite/federated/optimizer.result create mode 100644 mysql-test/suite/federated/optimizer.test (limited to 'mysql-test/suite/federated') diff --git a/mysql-test/suite/federated/optimizer.result b/mysql-test/suite/federated/optimizer.result new file mode 100644 index 00000000000..5d7072e0b35 --- /dev/null +++ b/mysql-test/suite/federated/optimizer.result @@ -0,0 +1,52 @@ +connect master,127.0.0.1,root,,test,$MASTER_MYPORT,; +connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,; +connection master; +CREATE DATABASE federated; +connection slave; +CREATE DATABASE federated; +connection default; +# +# MDEV-14907 FEDERATEDX doesn't respect DISTINCT +# +CREATE TABLE t1 ( +`foo_id` bigint(20) unsigned NOT NULL, +`foo_name` varchar(255) DEFAULT NULL, +`parent_foo_id` bigint(20) unsigned DEFAULT NULL, +PRIMARY KEY (`foo_id`), +KEY `foo_name` (`foo_name`), +KEY `parent_foo_id` (`parent_foo_id`) +) DEFAULT CHARSET=utf8; +CREATE TABLE `fed_t1` ENGINE=FEDERATED DEFAULT CHARSET=utf8 CONNECTION='mysql://root@127.0.0.1:MASTER_PORT/test/t1'; +INSERT INTO t1 VALUES (968903, 'STRING - 0', 822857); +INSERT INTO t1 VALUES (968953, 'STRING - 1', 822857); +INSERT INTO t1 VALUES (971603, 'STRING - 2', 822857); +INSERT INTO t1 VALUES (971803, 'STRING - 3', 822857); +INSERT INTO t1 VALUES (975103, 'STRING - 4', 822857); +INSERT INTO t1 VALUES (822857, 'STRING', NULL); +select foo_id,parent_foo_id,foo_name from t1 where parent_foo_id = 822857 or foo_name like 'STRING%'; +foo_id parent_foo_id foo_name +968903 822857 STRING - 0 +968953 822857 STRING - 1 +971603 822857 STRING - 2 +971803 822857 STRING - 3 +975103 822857 STRING - 4 +822857 NULL STRING +explain +select foo_id,parent_foo_id,foo_name from fed_t1 where parent_foo_id = 822857 or foo_name like 'STRING%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE fed_t1 ALL foo_name,parent_foo_id NULL NULL NULL 6 Using where +select foo_id,parent_foo_id,foo_name from fed_t1 where parent_foo_id = 822857 or foo_name like 'STRING%'; +foo_id parent_foo_id foo_name +968903 822857 STRING - 0 +968953 822857 STRING - 1 +971603 822857 STRING - 2 +971803 822857 STRING - 3 +975103 822857 STRING - 4 +822857 NULL STRING +DROP TABLE fed_t1, t1; +connection master; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; +connection slave; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; diff --git a/mysql-test/suite/federated/optimizer.test b/mysql-test/suite/federated/optimizer.test new file mode 100644 index 00000000000..4263060fab5 --- /dev/null +++ b/mysql-test/suite/federated/optimizer.test @@ -0,0 +1,39 @@ +# +#Test optimizer flags related to federated tables +# + +--source have_federatedx.inc +--source include/federated.inc + +connection default; + +--echo # +--echo # MDEV-14907 FEDERATEDX doesn't respect DISTINCT +--echo # + +CREATE TABLE t1 ( + `foo_id` bigint(20) unsigned NOT NULL, + `foo_name` varchar(255) DEFAULT NULL, + `parent_foo_id` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`foo_id`), + KEY `foo_name` (`foo_name`), + KEY `parent_foo_id` (`parent_foo_id`) +) DEFAULT CHARSET=utf8; + +--replace_result $MASTER_MYPORT MASTER_PORT +eval CREATE TABLE `fed_t1` ENGINE=FEDERATED DEFAULT CHARSET=utf8 CONNECTION='mysql://root@127.0.0.1:$MASTER_MYPORT/test/t1'; +INSERT INTO t1 VALUES (968903, 'STRING - 0', 822857); +INSERT INTO t1 VALUES (968953, 'STRING - 1', 822857); +INSERT INTO t1 VALUES (971603, 'STRING - 2', 822857); +INSERT INTO t1 VALUES (971803, 'STRING - 3', 822857); +INSERT INTO t1 VALUES (975103, 'STRING - 4', 822857); +INSERT INTO t1 VALUES (822857, 'STRING', NULL); + +select foo_id,parent_foo_id,foo_name from t1 where parent_foo_id = 822857 or foo_name like 'STRING%'; + +explain +select foo_id,parent_foo_id,foo_name from fed_t1 where parent_foo_id = 822857 or foo_name like 'STRING%'; +select foo_id,parent_foo_id,foo_name from fed_t1 where parent_foo_id = 822857 or foo_name like 'STRING%'; +DROP TABLE fed_t1, t1; + +source include/federated_cleanup.inc; -- cgit v1.2.1 From 4504e6d14e71f53043c75b80e83f25938ac63bb1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 21 Jan 2022 12:40:20 +0100 Subject: test cases for MySQL bugs also fix a comment, and update a macro just in case --- mysql-test/suite/federated/rpl.result | 18 ++++++++++++++++++ mysql-test/suite/federated/rpl.test | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 mysql-test/suite/federated/rpl.result create mode 100644 mysql-test/suite/federated/rpl.test (limited to 'mysql-test/suite/federated') diff --git a/mysql-test/suite/federated/rpl.result b/mysql-test/suite/federated/rpl.result new file mode 100644 index 00000000000..71821411c91 --- /dev/null +++ b/mysql-test/suite/federated/rpl.result @@ -0,0 +1,18 @@ +include/master-slave.inc +[connection master] +create table t1 (a int primary key, b int); +connection slave; +rename table t1 to t2; +create table t1 (a int primary key, b int) engine=federated connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t2'; +connection master; +insert t1 values (1,1),(2,2),(3,1); +delete from t1 where a=2; +connection slave; +select * from t1; +a b +1 1 +3 1 +drop table t2; +connection master; +drop table t1; +include/rpl_end.inc diff --git a/mysql-test/suite/federated/rpl.test b/mysql-test/suite/federated/rpl.test new file mode 100644 index 00000000000..6ec4bec5a1a --- /dev/null +++ b/mysql-test/suite/federated/rpl.test @@ -0,0 +1,19 @@ +source include/have_binlog_format_row.inc; +source include/master-slave.inc; + +create table t1 (a int primary key, b int); + +sync_slave_with_master; +rename table t1 to t2; +evalp create table t1 (a int primary key, b int) engine=federated connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t2'; +connection master; + +insert t1 values (1,1),(2,2),(3,1); +delete from t1 where a=2; +sync_slave_with_master; +select * from t1; +drop table t2; + +connection master; +drop table t1; +source include/rpl_end.inc; -- cgit v1.2.1