Commit d887a692 authored by unknown's avatar unknown

This is the same patch as 1.1937, with small variable declaration changes, memory

deallocation cleanup


mysql-test/r/federated.result:
  new test results
mysql-test/t/federated.test:
  New tests, and added explains per Timour's suggestion. This will keep
          track of whether changes have been made to the optimiser that might affect
          Federated.
          Also changed the error codes to federated error codes in the error tests
sql/ha_federated.cc:
  1. Not using MAX_REMOTE_SIZE, so removed
           2. Changed all defines that were IO_SIZE to FEDERATED_QUERY_BUFFER_SIZE
           3. Now using Federated Error Codes
           4. Implemented ::info (gets valid 'records' number)
           5. Implemented ::read_range_first - now uses indexes in range operations
           6. Better allocation in get_share
           7. Cleaned up memory bug in get_share
           8. Better initial query "SELECT * FROM t1 WHERE 1=0" for check_foreign_data_src
           9. emit_key_part_name and emit_key_part_element for read_range_first to not
              have redundancy
           10. Made sure all 'append's pass length, and use append("") to ensure proper
               null termination of strings being built.
           11. Better message creation. If ER_QUERY_ON_FOREIGN_DATA_SRC, I also pass
               the actual error code and message from the foreign data src.
           12. Cleaned up how the result set and share->scheme is freed.
sql/share/errmsg.txt:
  New Federated error messages that are more tailored to the type of information
  we want to see when federated has an error.
mysql-test/include/federated.inc:
  New bitkeeper file, include file for separating setup from main test suite
mysql-test/include/federated_cleanup.inc:
  New BitKeeper file ``mysql-test/include/federated_cleanup.inc''
sql/ha_federated.h:
  Added comments where needed, one was already commented about
parent d49ddbd7
--source ./include/have_federated_db.inc
source ./include/master-slave.inc;
# remote table creation
connection slave;
--replicate-ignore-db=federated
stop slave;
--disable_warnings
# at this point, we are connected to master
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
connection master;
--disable_warnings
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
connection master;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
connection slave;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
...@@ -7,41 +7,47 @@ start slave; ...@@ -7,41 +7,47 @@ start slave;
stop slave; stop slave;
DROP DATABASE IF EXISTS federated; DROP DATABASE IF EXISTS federated;
CREATE DATABASE federated; CREATE DATABASE federated;
DROP DATABASE IF EXISTS federated;
CREATE DATABASE federated;
DROP TABLE IF EXISTS federated.t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
) )
DEFAULT CHARSET=latin1; DEFAULT CHARSET=latin1;
DROP DATABASE IF EXISTS federated; DROP TABLE IF EXISTS federated.t1;
CREATE DATABASE federated; Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
) )
ENGINE="FEDERATED" DEFAULT CHARSET=latin1 ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:@/too/many/items/federated/t1'; COMMENT='mysql://root@127.0.0.1:@/too/many/items/federated/t1';
ERROR HY000: Can't create table 'connection string is not in the correct format' (errno: 0) ERROR HY000: Can't create federated table. The data source connection string 'mysql://root@127.0.0.1:@/too/many/items/federated/t1' is not in the correct format
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
) )
ENGINE="FEDERATED" DEFAULT CHARSET=latin1 ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1'; COMMENT='mysql://root@127.0.0.1';
ERROR HY000: Can't create table 'connection string is not in the correct format' (errno: 0) ERROR HY000: Can't create federated table. The data source connection string 'mysql://root@127.0.0.1' is not in the correct format
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
) )
ENGINE="FEDERATED" DEFAULT CHARSET=latin1 ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t3'; COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t3';
ERROR HY000: Error running query on master: foreign table 't3' does not exist! ERROR HY000: Can't create federated table. Foreign data src error : ': 1146 : Table 'federated.t3' doesn't exist'
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
) )
ENGINE="FEDERATED" DEFAULT CHARSET=latin1 ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://user:pass@127.0.0.1:SLAVE_PORT/federated/t1'; COMMENT='mysql://user:pass@127.0.0.1:SLAVE_PORT/federated/t1';
ERROR 08S01: Error connecting to master: unable to connect to database 'federated' on host '127.0.0.1 as user 'user' ! ERROR HY000: Unable to connect to foreign data source - database ' database federated username user hostname 127.0.0.1'!
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
Warnings: Warnings:
Note 1051 Unknown table 't1' Note 1051 Unknown table 't1'
...@@ -124,18 +130,14 @@ CREATE TABLE federated.t1 ( ...@@ -124,18 +130,14 @@ CREATE TABLE federated.t1 (
`name` varchar(32) NOT NULL default '', `name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0', `other` int(20) NOT NULL default '0',
`created` datetime default '2004-04-04 04:04:04', `created` datetime default '2004-04-04 04:04:04',
PRIMARY KEY (`id`), PRIMARY KEY (`id`))
KEY `name` (`name`),
KEY `other_key` (`other`))
DEFAULT CHARSET=latin1; DEFAULT CHARSET=latin1;
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment, `id` int(20) NOT NULL auto_increment,
`name` varchar(32) NOT NULL default '', `name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0', `other` int(20) NOT NULL default '0',
`created` datetime default '2004-04-04 04:04:04', `created` datetime default '2004-04-04 04:04:04',
PRIMARY KEY (`id`), PRIMARY KEY (`id`))
KEY `name` (`name`),
KEY `other_key` (`other`))
ENGINE="FEDERATED" DEFAULT CHARSET=latin1 ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 (name, other) VALUES ('First Name', 11111); INSERT INTO federated.t1 (name, other) VALUES ('First Name', 11111);
...@@ -148,6 +150,9 @@ INSERT INTO federated.t1 (name, other) VALUES ('Seventh Name', 77777); ...@@ -148,6 +150,9 @@ INSERT INTO federated.t1 (name, other) VALUES ('Seventh Name', 77777);
INSERT INTO federated.t1 (name, other) VALUES ('Eigth Name', 88888); INSERT INTO federated.t1 (name, other) VALUES ('Eigth Name', 88888);
INSERT INTO federated.t1 (name, other) VALUES ('Ninth Name', 99999); INSERT INTO federated.t1 (name, other) VALUES ('Ninth Name', 99999);
INSERT INTO federated.t1 (name, other) VALUES ('Tenth Name', 101010); INSERT INTO federated.t1 (name, other) VALUES ('Tenth Name', 101010);
EXPLAIN SELECT * FROM federated.t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10
SELECT * FROM federated.t1; SELECT * FROM federated.t1;
id name other created id name other created
1 First Name 11111 2004-04-04 04:04:04 1 First Name 11111 2004-04-04 04:04:04
...@@ -160,18 +165,32 @@ id name other created ...@@ -160,18 +165,32 @@ id name other created
8 Eigth Name 88888 2004-04-04 04:04:04 8 Eigth Name 88888 2004-04-04 04:04:04
9 Ninth Name 99999 2004-04-04 04:04:04 9 Ninth Name 99999 2004-04-04 04:04:04
10 Tenth Name 101010 2004-04-04 04:04:04 10 Tenth Name 101010 2004-04-04 04:04:04
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
SELECT * FROM federated.t1 WHERE id = 5; SELECT * FROM federated.t1 WHERE id = 5;
id name other created id name other created
5 Fifth Name 55555 2004-04-04 04:04:04 5 Fifth Name 55555 2004-04-04 04:04:04
EXPLAIN SELECT * FROM federated.t1 WHERE name = 'Sixth Name';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
SELECT * FROM federated.t1 WHERE name = 'Sixth Name'; SELECT * FROM federated.t1 WHERE name = 'Sixth Name';
id name other created id name other created
6 Sixth Name 66666 2004-04-04 04:04:04 6 Sixth Name 66666 2004-04-04 04:04:04
EXPLAIN SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name'; SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
id name other created id name other created
6 Sixth Name 66666 2004-04-04 04:04:04 6 Sixth Name 66666 2004-04-04 04:04:04
SELECT * FROM federated.t1 WHERE other = 44444; EXPLAIN SELECT * FROM federated.t1 WHERE name = 'Sixth Name' AND other = 44444;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
SELECT * FROM federated.t1 WHERE name = 'Sixth Name' AND other = 44444;
id name other created id name other created
4 Fourth Name 44444 2004-04-04 04:04:04 EXPLAIN SELECT * FROM federated.t1 WHERE name like '%th%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
SELECT * FROM federated.t1 WHERE name like '%th%'; SELECT * FROM federated.t1 WHERE name like '%th%';
id name other created id name other created
3 Third Name 33333 2004-04-04 04:04:04 3 Third Name 33333 2004-04-04 04:04:04
...@@ -190,6 +209,9 @@ UPDATE federated.t1 SET name = 'Third name' WHERE name = '3rd name'; ...@@ -190,6 +209,9 @@ UPDATE federated.t1 SET name = 'Third name' WHERE name = '3rd name';
SELECT * FROM federated.t1 WHERE name = 'Third name'; SELECT * FROM federated.t1 WHERE name = 'Third name';
id name other created id name other created
3 Third name 33333 2004-04-04 04:04:04 3 Third name 33333 2004-04-04 04:04:04
EXPLAIN SELECT * FROM federated.t1 ORDER BY id DESC;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using filesort
SELECT * FROM federated.t1 ORDER BY id DESC; SELECT * FROM federated.t1 ORDER BY id DESC;
id name other created id name other created
10 Tenth Name 101010 2004-04-04 04:04:04 10 Tenth Name 101010 2004-04-04 04:04:04
...@@ -202,6 +224,9 @@ id name other created ...@@ -202,6 +224,9 @@ id name other created
3 Third name 33333 2004-04-04 04:04:04 3 Third name 33333 2004-04-04 04:04:04
2 Second Name 22222 2004-04-04 04:04:04 2 Second Name 22222 2004-04-04 04:04:04
1 First Name 11111 2004-04-04 04:04:04 1 First Name 11111 2004-04-04 04:04:04
EXPLAIN SELECT * FROM federated.t1 ORDER BY name;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using filesort
SELECT * FROM federated.t1 ORDER BY name; SELECT * FROM federated.t1 ORDER BY name;
id name other created id name other created
8 Eigth Name 88888 2004-04-04 04:04:04 8 Eigth Name 88888 2004-04-04 04:04:04
...@@ -214,6 +239,9 @@ id name other created ...@@ -214,6 +239,9 @@ id name other created
6 Sixth Name 66666 2004-04-04 04:04:04 6 Sixth Name 66666 2004-04-04 04:04:04
10 Tenth Name 101010 2004-04-04 04:04:04 10 Tenth Name 101010 2004-04-04 04:04:04
3 Third name 33333 2004-04-04 04:04:04 3 Third name 33333 2004-04-04 04:04:04
EXPLAIN SELECT * FROM federated.t1 ORDER BY name DESC;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using filesort
SELECT * FROM federated.t1 ORDER BY name DESC; SELECT * FROM federated.t1 ORDER BY name DESC;
id name other created id name other created
3 Third name 33333 2004-04-04 04:04:04 3 Third name 33333 2004-04-04 04:04:04
...@@ -226,6 +254,9 @@ id name other created ...@@ -226,6 +254,9 @@ id name other created
1 First Name 11111 2004-04-04 04:04:04 1 First Name 11111 2004-04-04 04:04:04
5 Fifth Name 55555 2004-04-04 04:04:04 5 Fifth Name 55555 2004-04-04 04:04:04
8 Eigth Name 88888 2004-04-04 04:04:04 8 Eigth Name 88888 2004-04-04 04:04:04
EXPLAIN SELECT * FROM federated.t1 ORDER BY name ASC;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using filesort
SELECT * FROM federated.t1 ORDER BY name ASC; SELECT * FROM federated.t1 ORDER BY name ASC;
id name other created id name other created
8 Eigth Name 88888 2004-04-04 04:04:04 8 Eigth Name 88888 2004-04-04 04:04:04
...@@ -238,6 +269,9 @@ id name other created ...@@ -238,6 +269,9 @@ id name other created
6 Sixth Name 66666 2004-04-04 04:04:04 6 Sixth Name 66666 2004-04-04 04:04:04
10 Tenth Name 101010 2004-04-04 04:04:04 10 Tenth Name 101010 2004-04-04 04:04:04
3 Third name 33333 2004-04-04 04:04:04 3 Third name 33333 2004-04-04 04:04:04
EXPLAIN SELECT * FROM federated.t1 GROUP BY other;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
SELECT * FROM federated.t1 GROUP BY other; SELECT * FROM federated.t1 GROUP BY other;
id name other created id name other created
1 First Name 11111 2004-04-04 04:04:04 1 First Name 11111 2004-04-04 04:04:04
...@@ -257,6 +291,175 @@ DELETE FROM federated.t1; ...@@ -257,6 +291,175 @@ DELETE FROM federated.t1;
SELECT * FROM federated.t1 WHERE id = 5; SELECT * FROM federated.t1 WHERE id = 5;
id name other created id name other created
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment,
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime NOT NULL,
PRIMARY KEY (`id`),
key name(`name`),
key other(`other`),
key created(`created`))
DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment,
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime NOT NULL,
PRIMARY KEY (`id`),
key name(`name`),
key other(`other`),
key created(`created`))
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 (name, other, created)
VALUES ('First Name', 11111, '2004-01-01 01:01:01');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Second Name', 22222, '2004-01-23 02:43:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Third Name', 33333, '2004-02-14 02:14:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Fourth Name', 44444, '2003-04-05 00:00:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Fifth Name', 55555, '2001-02-02 02:02:02');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Sixth Name', 66666, '2005-06-06 15:30:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Seventh Name', 77777, '2003-12-12 18:32:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Eigth Name', 88888, '2005-03-12 11:00:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Ninth Name', 99999, '2005-03-12 11:00:01');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Tenth Name', 101010, '2005-03-12 12:00:01');
EXPLAIN SELECT * FROM federated.t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10
SELECT * FROM federated.t1;
id name other created
1 First Name 11111 2004-01-01 01:01:01
2 Second Name 22222 2004-01-23 02:43:00
3 Third Name 33333 2004-02-14 02:14:00
4 Fourth Name 44444 2003-04-05 00:00:00
5 Fifth Name 55555 2001-02-02 02:02:02
6 Sixth Name 66666 2005-06-06 15:30:00
7 Seventh Name 77777 2003-12-12 18:32:00
8 Eigth Name 88888 2005-03-12 11:00:00
9 Ninth Name 99999 2005-03-12 11:00:01
10 Tenth Name 101010 2005-03-12 12:00:01
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
SELECT * FROM federated.t1 WHERE id = 5;
id name other created
5 Fifth Name 55555 2001-02-02 02:02:02
EXPLAIN SELECT * FROM federated.t1 WHERE name = 'Sixth Name';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref name name 34 const 2 Using where
SELECT * FROM federated.t1 WHERE name = 'Sixth Name';
id name other created
6 Sixth Name 66666 2005-06-06 15:30:00
EXPLAIN SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY,name PRIMARY 4 const 1
SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
id name other created
6 Sixth Name 66666 2005-06-06 15:30:00
EXPLAIN SELECT * FROM federated.t1 WHERE other = 44444;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref other other 4 const 2
SELECT * FROM federated.t1 WHERE other = 44444;
id name other created
4 Fourth Name 44444 2003-04-05 00:00:00
EXPLAIN SELECT * FROM federated.t1 WHERE name like '%th%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
SELECT * FROM federated.t1 WHERE name like '%th%';
id name other created
3 Third Name 33333 2004-02-14 02:14:00
4 Fourth Name 44444 2003-04-05 00:00:00
5 Fifth Name 55555 2001-02-02 02:02:02
6 Sixth Name 66666 2005-06-06 15:30:00
7 Seventh Name 77777 2003-12-12 18:32:00
8 Eigth Name 88888 2005-03-12 11:00:00
9 Ninth Name 99999 2005-03-12 11:00:01
10 Tenth Name 101010 2005-03-12 12:00:01
UPDATE federated.t1 SET name = '3rd name' WHERE id = 3;
SELECT * FROM federated.t1 WHERE name = '3rd name';
id name other created
3 3rd name 33333 2004-02-14 02:14:00
UPDATE federated.t1 SET name = 'Third name' WHERE name = '3rd name';
SELECT * FROM federated.t1 WHERE name = 'Third name';
id name other created
3 Third name 33333 2004-02-14 02:14:00
SELECT * FROM federated.t1 ORDER BY id DESC;
id name other created
10 Tenth Name 101010 2005-03-12 12:00:01
9 Ninth Name 99999 2005-03-12 11:00:01
8 Eigth Name 88888 2005-03-12 11:00:00
7 Seventh Name 77777 2003-12-12 18:32:00
6 Sixth Name 66666 2005-06-06 15:30:00
5 Fifth Name 55555 2001-02-02 02:02:02
4 Fourth Name 44444 2003-04-05 00:00:00
3 Third name 33333 2004-02-14 02:14:00
2 Second Name 22222 2004-01-23 02:43:00
1 First Name 11111 2004-01-01 01:01:01
SELECT * FROM federated.t1 ORDER BY name;
id name other created
8 Eigth Name 88888 2005-03-12 11:00:00
5 Fifth Name 55555 2001-02-02 02:02:02
1 First Name 11111 2004-01-01 01:01:01
4 Fourth Name 44444 2003-04-05 00:00:00
9 Ninth Name 99999 2005-03-12 11:00:01
2 Second Name 22222 2004-01-23 02:43:00
7 Seventh Name 77777 2003-12-12 18:32:00
6 Sixth Name 66666 2005-06-06 15:30:00
10 Tenth Name 101010 2005-03-12 12:00:01
3 Third name 33333 2004-02-14 02:14:00
SELECT * FROM federated.t1 ORDER BY name DESC;
id name other created
3 Third name 33333 2004-02-14 02:14:00
10 Tenth Name 101010 2005-03-12 12:00:01
6 Sixth Name 66666 2005-06-06 15:30:00
7 Seventh Name 77777 2003-12-12 18:32:00
2 Second Name 22222 2004-01-23 02:43:00
9 Ninth Name 99999 2005-03-12 11:00:01
4 Fourth Name 44444 2003-04-05 00:00:00
1 First Name 11111 2004-01-01 01:01:01
5 Fifth Name 55555 2001-02-02 02:02:02
8 Eigth Name 88888 2005-03-12 11:00:00
SELECT * FROM federated.t1 ORDER BY name ASC;
id name other created
8 Eigth Name 88888 2005-03-12 11:00:00
5 Fifth Name 55555 2001-02-02 02:02:02
1 First Name 11111 2004-01-01 01:01:01
4 Fourth Name 44444 2003-04-05 00:00:00
9 Ninth Name 99999 2005-03-12 11:00:01
2 Second Name 22222 2004-01-23 02:43:00
7 Seventh Name 77777 2003-12-12 18:32:00
6 Sixth Name 66666 2005-06-06 15:30:00
10 Tenth Name 101010 2005-03-12 12:00:01
3 Third name 33333 2004-02-14 02:14:00
SELECT * FROM federated.t1 GROUP BY other;
id name other created
1 First Name 11111 2004-01-01 01:01:01
2 Second Name 22222 2004-01-23 02:43:00
3 Third name 33333 2004-02-14 02:14:00
4 Fourth Name 44444 2003-04-05 00:00:00
5 Fifth Name 55555 2001-02-02 02:02:02
6 Sixth Name 66666 2005-06-06 15:30:00
7 Seventh Name 77777 2003-12-12 18:32:00
8 Eigth Name 88888 2005-03-12 11:00:00
9 Ninth Name 99999 2005-03-12 11:00:01
10 Tenth Name 101010 2005-03-12 12:00:01
DELETE FROM federated.t1 WHERE id = 5;
SELECT * FROM federated.t1 WHERE id = 5;
id name other created
DELETE FROM federated.t1;
SELECT * FROM federated.t1 WHERE id = 5;
id name other created
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment, `id` int(20) NOT NULL auto_increment,
`name` varchar(32), `name` varchar(32),
...@@ -303,15 +506,14 @@ UPDATE federated.t1 ...@@ -303,15 +506,14 @@ UPDATE federated.t1
SET name = 'Fourth Name', other = 'four four four' SET name = 'Fourth Name', other = 'four four four'
WHERE name IS NULL AND other IS NULL; WHERE name IS NULL AND other IS NULL;
UPDATE federated.t1 SET other = 'two two two two' WHERE name = 'Second Name'; UPDATE federated.t1 SET other = 'two two two two' WHERE name = 'Second Name';
UPDATE federated.t1 SET other = 'seven seven' WHERE name like 'Sec%'; UPDATE federated.t1 SET other = 'seven seven' WHERE name like 'Sev%';
UPDATE federated.t1 SET other = 'seven seven' WHERE name = 'Seventh Name';
UPDATE federated.t1 SET name = 'Tenth Name' WHERE other like 'fee fie%'; UPDATE federated.t1 SET name = 'Tenth Name' WHERE other like 'fee fie%';
SELECT * FROM federated.t1 WHERE name IS NULL OR other IS NULL ; SELECT * FROM federated.t1 WHERE name IS NULL OR other IS NULL ;
id name other id name other
SELECT * FROM federated.t1; SELECT * FROM federated.t1;
id name other id name other
1 First Name 11111 1 First Name 11111
2 Second Name seven seven 2 Second Name two two two two
3 Third Name 33333 3 Third Name 33333
4 Fourth Name four four four 4 Fourth Name four four four
5 Fifth Name 55555 5 Fifth Name 55555
...@@ -418,6 +620,533 @@ id name bincol floatval other ...@@ -418,6 +620,533 @@ id name bincol floatval other
3 third g 22.22 2222 3 third g 22.22 2222
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int NOT NULL auto_increment,
`col1` int(10) NOT NULL DEFAULT 0,
`col2` varchar(64) NOT NULL DEFAULT '',
`col3` int(20) NOT NULL,
`col4` int(40) NOT NULL,
primary key (`id`, `col1`, `col2`, `col3`, `col4`),
key col1(col1),
key col2(col2),
key col3(col3),
key col4(col4));
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int NOT NULL auto_increment,
`col1` int(10) NOT NULL DEFAULT 0,
`col2` varchar(64) NOT NULL DEFAULT '',
`col3` int(20) NOT NULL,
`col4` int(40) NOT NULL,
primary key (`id`, `col1`, `col2`, `col3`, `col4`),
key col1(col1),
key col2(col2),
key col3(col3),
key col4(col4))
ENGINE="FEDERATED"
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (1, 'one One', 11, 1111);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (2, 'Two two', 22, 2222);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (3, 'three Three', 33, 33333);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (4, 'fourfourfour', 444, 4444444);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (5, 'five 5 five five 5', 5, 55555);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (6, 'six six Sixsix', 6666, 6);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (7, 'seven Sevenseven', 77777, 7777);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (8, 'eight eight eight', 88888, 88);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (9, 'nine Nine', 999999, 999999);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (10, 'Tenth ten TEN', 1010101, 1010);
EXPLAIN SELECT * FROM federated.t1 WHERE col2 = 'two two';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref col2 col2 66 const 2 Using where
SELECT * FROM federated.t1 WHERE col2 = 'two two';
id col1 col2 col3 col4
2 2 Two two 22 2222
EXPLAIN SELECT * FROM federated.t1 WHERE col2 = 'two Two';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref col2 col2 66 const 2 Using where
SELECT * FROM federated.t1 WHERE col2 = 'two Two';
id col1 col2 col3 col4
2 2 Two two 22 2222
SELECT * FROM federated.t1 WHERE id = 3;
id col1 col2 col3 col4
3 3 three Three 33 33333
EXPLAIN SELECT * FROM federated.t1 WHERE id = 3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY PRIMARY 4 const 2
SELECT * FROM federated.t1 WHERE id = 3 AND col1 = 3;
id col1 col2 col3 col4
3 3 three Three 33 33333
EXPLAIN SELECT * FROM federated.t1 WHERE id = 3 AND col1 = 3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,col1 PRIMARY 8 const,const 2
SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'Two two';
id col1 col2 col3 col4
EXPLAIN SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'Two two';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,col1,col2 PRIMARY 74 const,const,const 2 Using where
SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'fourfourfour';
id col1 col2 col3 col4
4 4 fourfourfour 444 4444444
EXPLAIN SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'fourfourfour';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,col1,col2 PRIMARY 74 const,const,const 2 Using where
SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5;
id col1 col2 col3 col4
5 5 five 5 five five 5 5 55555
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,col2,col3 PRIMARY 4 const 2 Using where
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5
AND col4 = 55555;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,col2,col3,col4 PRIMARY 4 const 2 Using where
SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5
AND col4 = 55555;
id col1 col2 col3 col4
5 5 five 5 five five 5 5 55555
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'Two two' AND col3 = 22
AND col4 = 33;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,col2,col3,col4 PRIMARY 4 const 2 Using where
SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'Two two' AND col3 = 22
AND col4 = 33;
id col1 col2 col3 col4
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'five 5 five five 5' AND col3 = 5
AND col4 = 55555;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,col2,col3,col4 PRIMARY 4 const 2 Using where
SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'five 5 five five 5' AND col3 = 5
AND col4 = 55555;
id col1 col2 col3 col4
5 5 five 5 five five 5 5 55555
EXPLAIN SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'five 5 five five 5')
OR (col2 = 'three Three' AND col3 = 33);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,col2,col3 col2 66 NULL 4 Using where
SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'five 5 five five 5')
OR (col2 = 'three Three' AND col3 = 33);
id col1 col2 col3 col4
5 5 five 5 five five 5 5 55555
3 3 three Three 33 33333
EXPLAIN SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'five 5 five five 5')
OR (col2 = 'three Three' AND col3 = 33)
OR col4 = 1010;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL PRIMARY,col2,col3,col4 NULL NULL NULL 10 Using where
SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'five 5 five five 5')
OR (col2 = 'three Three' AND col3 = 33)
OR col4 = 1010;
id col1 col2 col3 col4
3 3 three Three 33 33333
5 5 five 5 five five 5 5 55555
10 10 Tenth ten TEN 1010101 1010
EXPLAIN SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'Two two')
OR (col2 = 444 AND col3 = 4444444);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL PRIMARY,col2,col3 NULL NULL NULL 10 Using where
SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'Two two')
OR (col2 = 444 AND col3 = 4444444);
id col1 col2 col3 col4
EXPLAIN SELECT * FROM federated.t1 WHERE id = 1
OR col1 = 10
OR col2 = 'Two two'
OR col3 = 33
OR col4 = 4444444;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL PRIMARY,col1,col2,col3,col4 NULL NULL NULL 10 Using where
SELECT * FROM federated.t1 WHERE id = 1
OR col1 = 10
OR col2 = 'Two two'
OR col3 = 33
OR col4 = 4444444;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
10 10 Tenth ten TEN 1010101 1010
EXPLAIN SELECT * FROM federated.t1 WHERE id > 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
SELECT * FROM federated.t1 WHERE id > 5;
id col1 col2 col3 col4
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
8 8 eight eight eight 88888 88
9 9 nine Nine 999999 999999
10 10 Tenth ten TEN 1010101 1010
EXPLAIN SELECT * FROM federated.t1 WHERE id >= 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
SELECT * FROM federated.t1 WHERE id >= 5;
id col1 col2 col3 col4
5 5 five 5 five five 5 5 55555
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
8 8 eight eight eight 88888 88
9 9 nine Nine 999999 999999
10 10 Tenth ten TEN 1010101 1010
EXPLAIN SELECT * FROM federated.t1 WHERE id < 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
SELECT * FROM federated.t1 WHERE id < 5;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
EXPLAIN SELECT * FROM federated.t1 WHERE id <= 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
SELECT * FROM federated.t1 WHERE id <= 5;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
EXPLAIN SELECT * FROM federated.t1 WHERE id != 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where
SELECT * FROM federated.t1 WHERE id != 5;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
8 8 eight eight eight 88888 88
9 9 nine Nine 999999 999999
10 10 Tenth ten TEN 1010101 1010
EXPLAIN SELECT * FROM federated.t1 WHERE id > 3 AND id < 7;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
SELECT * FROM federated.t1 WHERE id > 3 AND id < 7;
id col1 col2 col3 col4
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
6 6 six six Sixsix 6666 6
EXPLAIN SELECT * FROM federated.t1 WHERE id > 3 AND id <= 7;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
SELECT * FROM federated.t1 WHERE id > 3 AND id <= 7;
id col1 col2 col3 col4
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
EXPLAIN SELECT * FROM federated.t1 WHERE id >= 3 AND id <= 7;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
SELECT * FROM federated.t1 WHERE id >= 3 AND id <= 7;
id col1 col2 col3 col4
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
EXPLAIN SELECT * FROM federated.t1 WHERE id < 3 AND id <= 7;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
SELECT * FROM federated.t1 WHERE id < 3 AND id <= 7;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
EXPLAIN SELECT * FROM federated.t1 WHERE id < 3 AND id > 7;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
SELECT * FROM federated.t1 WHERE id < 3 AND id > 7;
id col1 col2 col3 col4
EXPLAIN SELECT * FROM federated.t1 WHERE id < 3 OR id > 7;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where
SELECT * FROM federated.t1 WHERE id < 3 OR id > 7;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
8 8 eight eight eight 88888 88
9 9 nine Nine 999999 999999
10 10 Tenth ten TEN 1010101 1010
EXPLAIN SELECT * FROM federated.t1 WHERE col2 = 'three Three';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref col2 col2 66 const 2 Using where
SELECT * FROM federated.t1 WHERE col2 = 'three Three';
id col1 col2 col3 col4
3 3 three Three 33 33333
EXPLAIN SELECT * FROM federated.t1 WHERE col2 > 'one';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range col2 col2 66 NULL 2 Using where
SELECT * FROM federated.t1 WHERE col2 > 'one';
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
10 10 Tenth ten TEN 1010101 1010
EXPLAIN SELECT * FROM federated.t1 WHERE col2 LIKE 's%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range col2 col2 66 NULL 2 Using where
SELECT * FROM federated.t1 WHERE col2 LIKE 's%';
id col1 col2 col3 col4
7 7 seven Sevenseven 77777 7777
6 6 six six Sixsix 6666 6
EXPLAIN SELECT * FROM federated.t1 WHERE col2 LIKE 'si%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range col2 col2 66 NULL 2 Using where
SELECT * FROM federated.t1 WHERE col2 LIKE 'si%';
id col1 col2 col3 col4
6 6 six six Sixsix 6666 6
EXPLAIN SELECT * FROM federated.t1 WHERE col2 LIKE 'se%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range col2 col2 66 NULL 2 Using where
SELECT * FROM federated.t1 WHERE col2 LIKE 'se%';
id col1 col2 col3 col4
7 7 seven Sevenseven 77777 7777
EXPLAIN SELECT * FROM federated.t1 WHERE col2 NOT LIKE 'e%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
SELECT * FROM federated.t1 WHERE col2 NOT LIKE 'e%';
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
9 9 nine Nine 999999 999999
10 10 Tenth ten TEN 1010101 1010
EXPLAIN SELECT * FROM federated.t1 WHERE col2 <> 'one One';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range col2 col2 66 NULL 4 Using where
SELECT * FROM federated.t1 WHERE col2 <> 'one One';
id col1 col2 col3 col4
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
8 8 eight eight eight 88888 88
9 9 nine Nine 999999 999999
2 2 Two two 22 2222
3 3 three Three 33 33333
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
10 10 Tenth ten TEN 1010101 1010
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(128) NOT NULL DEFAULT '',
`col3` varchar(20) NOT NULL DEFAULT '',
`col4` varchar(40) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`, `col4`),
key 3key(`col2`,`col3`,`col4`),
key 2key (`col3`,`col4`),
key col4(col4));
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(128) NOT NULL DEFAULT '',
`col3` varchar(20) NOT NULL DEFAULT '',
`col4` varchar(40) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`, `col4`),
key 3key(`col2`,`col3`,`col4`),
key 2key (`col3`,`col4`),
key col4(col4))
ENGINE="FEDERATED"
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('aaaa', 'aaaaaaaaaaaaaaaaaaa', 'ababababab', 'acacacacacacacac');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('bbbb', 'bbbbbbbbbbbbbbbbbbb', 'bababababa', 'bcbcbcbcbcbcbcbc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('cccc', 'ccccccccccccccccccc', 'cacacacaca', 'cbcbcbcbcbcbcbcb');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('dddd', 'ddddddddddddddddddd', 'dadadadada', 'dcdcdcdcdcdcdcdc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('eeee', 'eeeeeeeeeeeeeeeeeee', 'eaeaeaeaea', 'ecececececececec');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('ffff', 'fffffffffffffffffff', 'fafafafafa', 'fcfcfcfcfcfcfcfc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('gggg', 'ggggggggggggggggggg', 'gagagagaga', 'gcgcgcgcgcgcgcgc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('hhhh', 'hhhhhhhhhhhhhhhhhhh', 'hahahahaha', 'hchchchchchchchc');
EXPLAIN SELECT * FROM federated.t1 WHERE col1 = 'cccc';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY PRIMARY 10 const 2 Using where
SELECT * FROM federated.t1 WHERE col1 = 'cccc';
col1 col2 col3 col4
cccc ccccccccccccccccccc cacacacaca cbcbcbcbcbcbcbcb
EXPLAIN SELECT * FROM federated.t1 WHERE col2 = 'eeeeeeeeeeeeeeeeeee';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref 3key 3key 130 const 2 Using where
SELECT * FROM federated.t1 WHERE col2 = 'eeeeeeeeeeeeeeeeeee';
col1 col2 col3 col4
eeee eeeeeeeeeeeeeeeeeee eaeaeaeaea ecececececececec
EXPLAIN SELECT * FROM federated.t1 WHERE col3 = 'bababababa';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref 2key 2key 22 const 2 Using where
SELECT * FROM federated.t1 WHERE col3 = 'bababababa';
col1 col2 col3 col4
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
EXPLAIN SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col2 = 'ggggggggggggggggggg';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,3key PRIMARY 140 const,const 2 Using where
SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col2 = 'ggggggggggggggggggg';
col1 col2 col3 col4
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
EXPLAIN SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col3 = 'gagagagaga';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,2key PRIMARY 10 const 2 Using where
SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col3 = 'gagagagaga';
col1 col2 col3 col4
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
EXPLAIN SELECT * FROM federated.t1 WHERE col1 = 'ffff' AND col4 = 'fcfcfcfcfcfcfcfc';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,col4 PRIMARY 10 const 2 Using where
SELECT * FROM federated.t1 WHERE col1 = 'ffff' AND col4 = 'fcfcfcfcfcfcfcfc';
col1 col2 col3 col4
ffff fffffffffffffffffff fafafafafa fcfcfcfcfcfcfcfc
EXPLAIN SELECT * FROM federated.t1 WHERE col1 > 'bbbb';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 10 NULL 2 Using where
SELECT * FROM federated.t1 WHERE col1 > 'bbbb';
col1 col2 col3 col4
cccc ccccccccccccccccccc cacacacaca cbcbcbcbcbcbcbcb
dddd ddddddddddddddddddd dadadadada dcdcdcdcdcdcdcdc
eeee eeeeeeeeeeeeeeeeeee eaeaeaeaea ecececececececec
ffff fffffffffffffffffff fafafafafa fcfcfcfcfcfcfcfc
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
hhhh hhhhhhhhhhhhhhhhhhh hahahahaha hchchchchchchchc
EXPLAIN SELECT * FROM federated.t1 WHERE col1 >= 'bbbb';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 10 NULL 2 Using where
SELECT * FROM federated.t1 WHERE col1 >= 'bbbb';
col1 col2 col3 col4
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
cccc ccccccccccccccccccc cacacacaca cbcbcbcbcbcbcbcb
dddd ddddddddddddddddddd dadadadada dcdcdcdcdcdcdcdc
eeee eeeeeeeeeeeeeeeeeee eaeaeaeaea ecececececececec
ffff fffffffffffffffffff fafafafafa fcfcfcfcfcfcfcfc
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
hhhh hhhhhhhhhhhhhhhhhhh hahahahaha hchchchchchchchc
EXPLAIN SELECT * FROM federated.t1 WHERE col1 < 'bbbb';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 10 NULL 2 Using where
SELECT * FROM federated.t1 WHERE col1 < 'bbbb';
col1 col2 col3 col4
aaaa aaaaaaaaaaaaaaaaaaa ababababab acacacacacacacac
EXPLAIN SELECT * FROM federated.t1 WHERE col1 <= 'bbbb';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 10 NULL 2 Using where
SELECT * FROM federated.t1 WHERE col1 <= 'bbbb';
col1 col2 col3 col4
aaaa aaaaaaaaaaaaaaaaaaa ababababab acacacacacacacac
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
EXPLAIN SELECT * FROM federated.t1 WHERE col1 <> 'bbbb';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 10 NULL 4 Using where
SELECT * FROM federated.t1 WHERE col1 <> 'bbbb';
col1 col2 col3 col4
aaaa aaaaaaaaaaaaaaaaaaa ababababab acacacacacacacac
cccc ccccccccccccccccccc cacacacaca cbcbcbcbcbcbcbcb
dddd ddddddddddddddddddd dadadadada dcdcdcdcdcdcdcdc
eeee eeeeeeeeeeeeeeeeeee eaeaeaeaea ecececececececec
ffff fffffffffffffffffff fafafafafa fcfcfcfcfcfcfcfc
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
hhhh hhhhhhhhhhhhhhhhhhh hahahahaha hchchchchchchchc
EXPLAIN SELECT * FROM federated.t1 WHERE col1 LIKE 'b%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 10 NULL 2 Using where
SELECT * FROM federated.t1 WHERE col1 LIKE 'b%';
col1 col2 col3 col4
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
EXPLAIN SELECT * FROM federated.t1 WHERE col4 LIKE '%b%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where
SELECT * FROM federated.t1 WHERE col4 LIKE '%b%';
col1 col2 col3 col4
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
cccc ccccccccccccccccccc cacacacaca cbcbcbcbcbcbcbcb
EXPLAIN SELECT * FROM federated.t1 WHERE col1 NOT LIKE 'c%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where
SELECT * FROM federated.t1 WHERE col1 NOT LIKE 'c%';
col1 col2 col3 col4
aaaa aaaaaaaaaaaaaaaaaaa ababababab acacacacacacacac
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
dddd ddddddddddddddddddd dadadadada dcdcdcdcdcdcdcdc
eeee eeeeeeeeeeeeeeeeeee eaeaeaeaea ecececececececec
ffff fffffffffffffffffff fafafafafa fcfcfcfcfcfcfcfc
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
hhhh hhhhhhhhhhhhhhhhhhh hahahahaha hchchchchchchchc
EXPLAIN SELECT * FROM federated.t1 WHERE col4 NOT LIKE '%c%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where
SELECT * FROM federated.t1 WHERE col4 NOT LIKE '%c%';
col1 col2 col3 col4
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` int(8) NOT NULL DEFAULT 0,
`col3` varchar(8) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`));
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(8) NOT NULL DEFAULT '',
`col3` varchar(8) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`))
ENGINE="FEDERATED"
DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 VALUES ('a00', '110', 'cc0');
INSERT INTO federated.t1 VALUES ('aaa', '111', 'ccc');
INSERT INTO federated.t1 VALUES ('bbb', '222', 'yyy');
INSERT INTO federated.t1 VALUES ('ccc', '111', 'zzz');
INSERT INTO federated.t1 VALUES ('ccd', '112', 'zzzz');
EXPLAIN SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 14 NULL 3 Using where; Using index
SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
col3
ccc
yyy
zzz
EXPLAIN SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 20 NULL 6 Using where
SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
col3
ccc
yyy
zzz
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int, `id` int,
`name` varchar(32), `name` varchar(32),
`floatval` float, `floatval` float,
...@@ -453,6 +1182,13 @@ AND floatval IS NULL ...@@ -453,6 +1182,13 @@ AND floatval IS NULL
AND other IS NULL; AND other IS NULL;
count(*) count(*)
2 2
EXPLAIN SELECT count(*) FROM federated.t1
WHERE id IS NULL
AND name IS NULL
AND floatval IS NULL
AND other IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`blurb_id` int NOT NULL DEFAULT 0, `blurb_id` int NOT NULL DEFAULT 0,
...@@ -496,28 +1232,28 @@ COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; ...@@ -496,28 +1232,28 @@ COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 VALUES (3,3,3),(1,1,1),(2,2,2),(4,4,4); INSERT INTO federated.t1 VALUES (3,3,3),(1,1,1),(2,2,2),(4,4,4);
EXPLAIN SELECT * FROM federated.t1 ORDER BY a; EXPLAIN SELECT * FROM federated.t1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort
EXPLAIN SELECT * FROM federated.t1 ORDER BY b; EXPLAIN SELECT * FROM federated.t1 ORDER BY b;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort
EXPLAIN SELECT * FROM federated.t1 ORDER BY c; EXPLAIN SELECT * FROM federated.t1 ORDER BY c;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort
EXPLAIN SELECT a FROM federated.t1 ORDER BY a; EXPLAIN SELECT a FROM federated.t1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort
EXPLAIN SELECT b FROM federated.t1 ORDER BY b; EXPLAIN SELECT b FROM federated.t1 ORDER BY b;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort
EXPLAIN SELECT a,b FROM federated.t1 ORDER BY b; EXPLAIN SELECT a,b FROM federated.t1 ORDER BY b;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort
EXPLAIN SELECT a,b FROM federated.t1; EXPLAIN SELECT a,b FROM federated.t1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 1 SIMPLE t1 ALL NULL NULL NULL NULL 4
EXPLAIN SELECT a,b,c FROM federated.t1; EXPLAIN SELECT a,b,c FROM federated.t1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 1 SIMPLE t1 ALL NULL NULL NULL NULL 4
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (i1 int, i2 int, i3 int, i4 int, i5 int, i6 int, i7 int, i8 CREATE TABLE federated.t1 (i1 int, i2 int, i3 int, i4 int, i5 int, i6 int, i7 int, i8
int, i9 int, i10 int, i11 int, i12 int, i13 int, i14 int, i15 int, i16 int, i17 int, i9 int, i10 int, i11 int, i12 int, i13 int, i14 int, i15 int, i16 int, i17
...@@ -817,6 +1553,9 @@ values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...@@ -817,6 +1553,9 @@ values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "PatrickG"); 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "PatrickG");
UPDATE federated.t1 SET b=repeat('a',256); UPDATE federated.t1 SET b=repeat('a',256);
UPDATE federated.t1 SET i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0, i10=0; UPDATE federated.t1 SET i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0, i10=0;
EXPLAIN SELECT * FROM federated.t1 WHERE i9=0 and i10=0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where
SELECT * FROM federated.t1 WHERE i9=0 and i10=0; SELECT * FROM federated.t1 WHERE i9=0 and i10=0;
i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 i21 i22 i23 i24 i25 i26 i27 i28 i29 i30 i31 i32 i33 i34 i35 i36 i37 i38 i39 i40 i41 i42 i43 i44 i45 i46 i47 i48 i49 i50 i51 i52 i53 i54 i55 i56 i57 i58 i59 i60 i61 i62 i63 i64 i65 i66 i67 i68 i69 i70 i71 i72 i73 i74 i75 i76 i77 i78 i79 i80 i81 i82 i83 i84 i85 i86 i87 i88 i89 i90 i91 i92 i93 i94 i95 i96 i97 i98 i99 i100 i101 i102 i103 i104 i105 i106 i107 i108 i109 i110 i111 i112 i113 i114 i115 i116 i117 i118 i119 i120 i121 i122 i123 i124 i125 i126 i127 i128 i129 i130 i131 i132 i133 i134 i135 i136 i137 i138 i139 i140 i141 i142 i143 i144 i145 i146 i147 i148 i149 i150 i151 i152 i153 i154 i155 i156 i157 i158 i159 i160 i161 i162 i163 i164 i165 i166 i167 i168 i169 i170 i171 i172 i173 i174 i175 i176 i177 i178 i179 i180 i181 i182 i183 i184 i185 i186 i187 i188 i189 i190 i191 i192 i193 i194 i195 i196 i197 i198 i199 i200 i201 i202 i203 i204 i205 i206 i207 i208 i209 i210 i211 i212 i213 i214 i215 i216 i217 i218 i219 i220 i221 i222 i223 i224 i225 i226 i227 i228 i229 i230 i231 i232 i233 i234 i235 i236 i237 i238 i239 i240 i241 i242 i243 i244 i245 i246 i247 i248 i249 i250 i251 i252 i253 i254 i255 i256 i257 i258 i259 i260 i261 i262 i263 i264 i265 i266 i267 i268 i269 i270 i271 i272 i273 i274 i275 i276 i277 i278 i279 i280 i281 i282 i283 i284 i285 i286 i287 i288 i289 i290 i291 i292 i293 i294 i295 i296 i297 i298 i299 i300 i301 i302 i303 i304 i305 i306 i307 i308 i309 i310 i311 i312 i313 i314 i315 i316 i317 i318 i319 i320 i321 i322 i323 i324 i325 i326 i327 i328 i329 i330 i331 i332 i333 i334 i335 i336 i337 i338 i339 i340 i341 i342 i343 i344 i345 i346 i347 i348 i349 i350 i351 i352 i353 i354 i355 i356 i357 i358 i359 i360 i361 i362 i363 i364 i365 i366 i367 i368 i369 i370 i371 i372 i373 i374 i375 i376 i377 i378 i379 i380 i381 i382 i383 i384 i385 i386 i387 i388 i389 i390 i391 i392 i393 i394 i395 i396 i397 i398 i399 i400 i401 i402 i403 i404 i405 i406 i407 i408 i409 i410 i411 i412 i413 i414 i415 i416 i417 i418 i419 i420 i421 i422 i423 i424 i425 i426 i427 i428 i429 i430 i431 i432 i433 i434 i435 i436 i437 i438 i439 i440 i441 i442 i443 i444 i445 i446 i447 i448 i449 i450 i451 i452 i453 i454 i455 i456 i457 i458 i459 i460 i461 i462 i463 i464 i465 i466 i467 i468 i469 i470 i471 i472 i473 i474 i475 i476 i477 i478 i479 i480 i481 i482 i483 i484 i485 i486 i487 i488 i489 i490 i491 i492 i493 i494 i495 i496 i497 i498 i499 i500 i501 i502 i503 i504 i505 i506 i507 i508 i509 i510 i511 i512 i513 i514 i515 i516 i517 i518 i519 i520 i521 i522 i523 i524 i525 i526 i527 i528 i529 i530 i531 i532 i533 i534 i535 i536 i537 i538 i539 i540 i541 i542 i543 i544 i545 i546 i547 i548 i549 i550 i551 i552 i553 i554 i555 i556 i557 i558 i559 i560 i561 i562 i563 i564 i565 i566 i567 i568 i569 i570 i571 i572 i573 i574 i575 i576 i577 i578 i579 i580 i581 i582 i583 i584 i585 i586 i587 i588 i589 i590 i591 i592 i593 i594 i595 i596 i597 i598 i599 i600 i601 i602 i603 i604 i605 i606 i607 i608 i609 i610 i611 i612 i613 i614 i615 i616 i617 i618 i619 i620 i621 i622 i623 i624 i625 i626 i627 i628 i629 i630 i631 i632 i633 i634 i635 i636 i637 i638 i639 i640 i641 i642 i643 i644 i645 i646 i647 i648 i649 i650 i651 i652 i653 i654 i655 i656 i657 i658 i659 i660 i661 i662 i663 i664 i665 i666 i667 i668 i669 i670 i671 i672 i673 i674 i675 i676 i677 i678 i679 i680 i681 i682 i683 i684 i685 i686 i687 i688 i689 i690 i691 i692 i693 i694 i695 i696 i697 i698 i699 i700 i701 i702 i703 i704 i705 i706 i707 i708 i709 i710 i711 i712 i713 i714 i715 i716 i717 i718 i719 i720 i721 i722 i723 i724 i725 i726 i727 i728 i729 i730 i731 i732 i733 i734 i735 i736 i737 i738 i739 i740 i741 i742 i743 i744 i745 i746 i747 i748 i749 i750 i751 i752 i753 i754 i755 i756 i757 i758 i759 i760 i761 i762 i763 i764 i765 i766 i767 i768 i769 i770 i771 i772 i773 i774 i775 i776 i777 i778 i779 i780 i781 i782 i783 i784 i785 i786 i787 i788 i789 i790 i791 i792 i793 i794 i795 i796 i797 i798 i799 i800 i801 i802 i803 i804 i805 i806 i807 i808 i809 i810 i811 i812 i813 i814 i815 i816 i817 i818 i819 i820 i821 i822 i823 i824 i825 i826 i827 i828 i829 i830 i831 i832 i833 i834 i835 i836 i837 i838 i839 i840 i841 i842 i843 i844 i845 i846 i847 i848 i849 i850 i851 i852 i853 i854 i855 i856 i857 i858 i859 i860 i861 i862 i863 i864 i865 i866 i867 i868 i869 i870 i871 i872 i873 i874 i875 i876 i877 i878 i879 i880 i881 i882 i883 i884 i885 i886 i887 i888 i889 i890 i891 i892 i893 i894 i895 i896 i897 i898 i899 i900 i901 i902 i903 i904 i905 i906 i907 i908 i909 i910 i911 i912 i913 i914 i915 i916 i917 i918 i919 i920 i921 i922 i923 i924 i925 i926 i927 i928 i929 i930 i931 i932 i933 i934 i935 i936 i937 i938 i939 i940 i941 i942 i943 i944 i945 i946 i947 i948 i949 i950 i951 i952 i953 i954 i955 i956 i957 i958 i959 i960 i961 i962 i963 i964 i965 i966 i967 i968 i969 i970 i971 i972 i973 i974 i975 i976 i977 i978 i979 i980 i981 i982 i983 i984 i985 i986 i987 i988 i989 i990 i991 i992 i993 i994 i995 i996 i997 i998 i999 i1000 b i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 i21 i22 i23 i24 i25 i26 i27 i28 i29 i30 i31 i32 i33 i34 i35 i36 i37 i38 i39 i40 i41 i42 i43 i44 i45 i46 i47 i48 i49 i50 i51 i52 i53 i54 i55 i56 i57 i58 i59 i60 i61 i62 i63 i64 i65 i66 i67 i68 i69 i70 i71 i72 i73 i74 i75 i76 i77 i78 i79 i80 i81 i82 i83 i84 i85 i86 i87 i88 i89 i90 i91 i92 i93 i94 i95 i96 i97 i98 i99 i100 i101 i102 i103 i104 i105 i106 i107 i108 i109 i110 i111 i112 i113 i114 i115 i116 i117 i118 i119 i120 i121 i122 i123 i124 i125 i126 i127 i128 i129 i130 i131 i132 i133 i134 i135 i136 i137 i138 i139 i140 i141 i142 i143 i144 i145 i146 i147 i148 i149 i150 i151 i152 i153 i154 i155 i156 i157 i158 i159 i160 i161 i162 i163 i164 i165 i166 i167 i168 i169 i170 i171 i172 i173 i174 i175 i176 i177 i178 i179 i180 i181 i182 i183 i184 i185 i186 i187 i188 i189 i190 i191 i192 i193 i194 i195 i196 i197 i198 i199 i200 i201 i202 i203 i204 i205 i206 i207 i208 i209 i210 i211 i212 i213 i214 i215 i216 i217 i218 i219 i220 i221 i222 i223 i224 i225 i226 i227 i228 i229 i230 i231 i232 i233 i234 i235 i236 i237 i238 i239 i240 i241 i242 i243 i244 i245 i246 i247 i248 i249 i250 i251 i252 i253 i254 i255 i256 i257 i258 i259 i260 i261 i262 i263 i264 i265 i266 i267 i268 i269 i270 i271 i272 i273 i274 i275 i276 i277 i278 i279 i280 i281 i282 i283 i284 i285 i286 i287 i288 i289 i290 i291 i292 i293 i294 i295 i296 i297 i298 i299 i300 i301 i302 i303 i304 i305 i306 i307 i308 i309 i310 i311 i312 i313 i314 i315 i316 i317 i318 i319 i320 i321 i322 i323 i324 i325 i326 i327 i328 i329 i330 i331 i332 i333 i334 i335 i336 i337 i338 i339 i340 i341 i342 i343 i344 i345 i346 i347 i348 i349 i350 i351 i352 i353 i354 i355 i356 i357 i358 i359 i360 i361 i362 i363 i364 i365 i366 i367 i368 i369 i370 i371 i372 i373 i374 i375 i376 i377 i378 i379 i380 i381 i382 i383 i384 i385 i386 i387 i388 i389 i390 i391 i392 i393 i394 i395 i396 i397 i398 i399 i400 i401 i402 i403 i404 i405 i406 i407 i408 i409 i410 i411 i412 i413 i414 i415 i416 i417 i418 i419 i420 i421 i422 i423 i424 i425 i426 i427 i428 i429 i430 i431 i432 i433 i434 i435 i436 i437 i438 i439 i440 i441 i442 i443 i444 i445 i446 i447 i448 i449 i450 i451 i452 i453 i454 i455 i456 i457 i458 i459 i460 i461 i462 i463 i464 i465 i466 i467 i468 i469 i470 i471 i472 i473 i474 i475 i476 i477 i478 i479 i480 i481 i482 i483 i484 i485 i486 i487 i488 i489 i490 i491 i492 i493 i494 i495 i496 i497 i498 i499 i500 i501 i502 i503 i504 i505 i506 i507 i508 i509 i510 i511 i512 i513 i514 i515 i516 i517 i518 i519 i520 i521 i522 i523 i524 i525 i526 i527 i528 i529 i530 i531 i532 i533 i534 i535 i536 i537 i538 i539 i540 i541 i542 i543 i544 i545 i546 i547 i548 i549 i550 i551 i552 i553 i554 i555 i556 i557 i558 i559 i560 i561 i562 i563 i564 i565 i566 i567 i568 i569 i570 i571 i572 i573 i574 i575 i576 i577 i578 i579 i580 i581 i582 i583 i584 i585 i586 i587 i588 i589 i590 i591 i592 i593 i594 i595 i596 i597 i598 i599 i600 i601 i602 i603 i604 i605 i606 i607 i608 i609 i610 i611 i612 i613 i614 i615 i616 i617 i618 i619 i620 i621 i622 i623 i624 i625 i626 i627 i628 i629 i630 i631 i632 i633 i634 i635 i636 i637 i638 i639 i640 i641 i642 i643 i644 i645 i646 i647 i648 i649 i650 i651 i652 i653 i654 i655 i656 i657 i658 i659 i660 i661 i662 i663 i664 i665 i666 i667 i668 i669 i670 i671 i672 i673 i674 i675 i676 i677 i678 i679 i680 i681 i682 i683 i684 i685 i686 i687 i688 i689 i690 i691 i692 i693 i694 i695 i696 i697 i698 i699 i700 i701 i702 i703 i704 i705 i706 i707 i708 i709 i710 i711 i712 i713 i714 i715 i716 i717 i718 i719 i720 i721 i722 i723 i724 i725 i726 i727 i728 i729 i730 i731 i732 i733 i734 i735 i736 i737 i738 i739 i740 i741 i742 i743 i744 i745 i746 i747 i748 i749 i750 i751 i752 i753 i754 i755 i756 i757 i758 i759 i760 i761 i762 i763 i764 i765 i766 i767 i768 i769 i770 i771 i772 i773 i774 i775 i776 i777 i778 i779 i780 i781 i782 i783 i784 i785 i786 i787 i788 i789 i790 i791 i792 i793 i794 i795 i796 i797 i798 i799 i800 i801 i802 i803 i804 i805 i806 i807 i808 i809 i810 i811 i812 i813 i814 i815 i816 i817 i818 i819 i820 i821 i822 i823 i824 i825 i826 i827 i828 i829 i830 i831 i832 i833 i834 i835 i836 i837 i838 i839 i840 i841 i842 i843 i844 i845 i846 i847 i848 i849 i850 i851 i852 i853 i854 i855 i856 i857 i858 i859 i860 i861 i862 i863 i864 i865 i866 i867 i868 i869 i870 i871 i872 i873 i874 i875 i876 i877 i878 i879 i880 i881 i882 i883 i884 i885 i886 i887 i888 i889 i890 i891 i892 i893 i894 i895 i896 i897 i898 i899 i900 i901 i902 i903 i904 i905 i906 i907 i908 i909 i910 i911 i912 i913 i914 i915 i916 i917 i918 i919 i920 i921 i922 i923 i924 i925 i926 i927 i928 i929 i930 i931 i932 i933 i934 i935 i936 i937 i938 i939 i940 i941 i942 i943 i944 i945 i946 i947 i948 i949 i950 i951 i952 i953 i954 i955 i956 i957 i958 i959 i960 i961 i962 i963 i964 i965 i966 i967 i968 i969 i970 i971 i972 i973 i974 i975 i976 i977 i978 i979 i980 i981 i982 i983 i984 i985 i986 i987 i988 i989 i990 i991 i992 i993 i994 i995 i996 i997 i998 i999 i1000 b
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
...@@ -912,7 +1651,7 @@ FROM federated.t1, federated.countries WHERE ...@@ -912,7 +1651,7 @@ FROM federated.t1, federated.countries WHERE
federated.t1.country_id = federated.countries.id; federated.t1.country_id = federated.countries.id;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE countries ALL PRIMARY NULL NULL NULL 5 1 SIMPLE countries ALL PRIMARY NULL NULL NULL 5
1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 120 1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 2
SELECT federated.t1.name AS name, federated.t1.country_id AS country_id, SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1, federated.countries WHERE FROM federated.t1, federated.countries WHERE
...@@ -929,7 +1668,7 @@ FROM federated.t1 INNER JOIN federated.countries ON ...@@ -929,7 +1668,7 @@ FROM federated.t1 INNER JOIN federated.countries ON
federated.t1.country_id = federated.countries.id; federated.t1.country_id = federated.countries.id;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE countries ALL PRIMARY NULL NULL NULL 5 1 SIMPLE countries ALL PRIMARY NULL NULL NULL 5
1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 120 1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 2
SELECT federated.t1.name AS name, federated.t1.country_id AS country_id, SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1 INNER JOIN federated.countries ON FROM federated.t1 INNER JOIN federated.countries ON
...@@ -947,7 +1686,7 @@ federated.t1.country_id = federated.countries.id ...@@ -947,7 +1686,7 @@ federated.t1.country_id = federated.countries.id
WHERE federated.t1.name = 'Monty'; WHERE federated.t1.name = 'Monty';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE countries ALL PRIMARY NULL NULL NULL 5 1 SIMPLE countries ALL PRIMARY NULL NULL NULL 5
1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 120 Using where 1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 2 Using where
SELECT federated.t1.name AS name, federated.t1.country_id AS country_id, SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1 INNER JOIN federated.countries ON FROM federated.t1 INNER JOIN federated.countries ON
...@@ -960,7 +1699,7 @@ FROM federated.t1 LEFT JOIN federated.countries ...@@ -960,7 +1699,7 @@ FROM federated.t1 LEFT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id ON federated.t1.country_id = federated.countries.id
ORDER BY federated.countries.id; ORDER BY federated.countries.id;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using temporary; Using filesort 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
1 SIMPLE countries eq_ref PRIMARY PRIMARY 4 federated.t1.country_id 1 1 SIMPLE countries eq_ref PRIMARY PRIMARY 4 federated.t1.country_id 1
SELECT federated.t1.*, federated.countries.country SELECT federated.t1.*, federated.countries.country
FROM federated.t1 LEFT JOIN federated.countries FROM federated.t1 LEFT JOIN federated.countries
...@@ -977,7 +1716,7 @@ FROM federated.t1 LEFT JOIN federated.countries ...@@ -977,7 +1716,7 @@ FROM federated.t1 LEFT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id ON federated.t1.country_id = federated.countries.id
ORDER BY federated.countries.country; ORDER BY federated.countries.country;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using temporary; Using filesort 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
1 SIMPLE countries eq_ref PRIMARY PRIMARY 4 federated.t1.country_id 1 1 SIMPLE countries eq_ref PRIMARY PRIMARY 4 federated.t1.country_id 1
SELECT federated.t1.*, federated.countries.country SELECT federated.t1.*, federated.countries.country
FROM federated.t1 LEFT JOIN federated.countries FROM federated.t1 LEFT JOIN federated.countries
...@@ -995,7 +1734,7 @@ ON federated.t1.country_id = federated.countries.id ...@@ -995,7 +1734,7 @@ ON federated.t1.country_id = federated.countries.id
ORDER BY federated.t1.country_id; ORDER BY federated.t1.country_id;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE countries ALL NULL NULL NULL NULL 5 Using temporary; Using filesort 1 SIMPLE countries ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 120 1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 2
SELECT federated.t1.*, federated.countries.country SELECT federated.t1.*, federated.countries.country
FROM federated.t1 RIGHT JOIN federated.countries FROM federated.t1 RIGHT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id ON federated.t1.country_id = federated.countries.id
......
--source include/have_federated_db.inc source include/federated.inc;
source include/master-slave.inc;
# remote table creation
connection slave; connection slave;
--replicate-ignore-db=federated DROP TABLE IF EXISTS federated.t1;
stop slave;
--disable_warnings
# at this point, we are connected to master
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
...@@ -21,14 +9,10 @@ CREATE TABLE federated.t1 ( ...@@ -21,14 +9,10 @@ CREATE TABLE federated.t1 (
DEFAULT CHARSET=latin1; DEFAULT CHARSET=latin1;
connection master; connection master;
--disable_warnings DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
# test too many items (malformed) in the comment string url # test too many items (malformed) in the comment string url
--error 1005 --error 1432
eval CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
) )
...@@ -36,8 +20,8 @@ eval CREATE TABLE federated.t1 ( ...@@ -36,8 +20,8 @@ eval CREATE TABLE federated.t1 (
COMMENT='mysql://root@127.0.0.1:@/too/many/items/federated/t1'; COMMENT='mysql://root@127.0.0.1:@/too/many/items/federated/t1';
# test not enough items (malformed) in the comment string url # test not enough items (malformed) in the comment string url
--error 1005 --error 1432
eval CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
) )
...@@ -46,7 +30,7 @@ eval CREATE TABLE federated.t1 ( ...@@ -46,7 +30,7 @@ eval CREATE TABLE federated.t1 (
# test non-existant table # test non-existant table
--replace_result $SLAVE_MYPORT SLAVE_PORT --replace_result $SLAVE_MYPORT SLAVE_PORT
--error 1219 --error 1434
eval CREATE TABLE federated.t1 ( eval CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
...@@ -56,7 +40,7 @@ eval CREATE TABLE federated.t1 ( ...@@ -56,7 +40,7 @@ eval CREATE TABLE federated.t1 (
# test bad user/password # test bad user/password
--replace_result $SLAVE_MYPORT SLAVE_PORT --replace_result $SLAVE_MYPORT SLAVE_PORT
--error 1218 --error 1429
eval CREATE TABLE federated.t1 ( eval CREATE TABLE federated.t1 (
`id` int(20) NOT NULL, `id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default '' `name` varchar(32) NOT NULL default ''
...@@ -150,12 +134,9 @@ CREATE TABLE federated.t1 ( ...@@ -150,12 +134,9 @@ CREATE TABLE federated.t1 (
`name` varchar(32) NOT NULL default '', `name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0', `other` int(20) NOT NULL default '0',
`created` datetime default '2004-04-04 04:04:04', `created` datetime default '2004-04-04 04:04:04',
PRIMARY KEY (`id`), PRIMARY KEY (`id`))
KEY `name` (`name`),
KEY `other_key` (`other`))
DEFAULT CHARSET=latin1; DEFAULT CHARSET=latin1;
connection master; connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT --replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 ( eval CREATE TABLE federated.t1 (
...@@ -163,9 +144,7 @@ eval CREATE TABLE federated.t1 ( ...@@ -163,9 +144,7 @@ eval CREATE TABLE federated.t1 (
`name` varchar(32) NOT NULL default '', `name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0', `other` int(20) NOT NULL default '0',
`created` datetime default '2004-04-04 04:04:04', `created` datetime default '2004-04-04 04:04:04',
PRIMARY KEY (`id`), PRIMARY KEY (`id`))
KEY `name` (`name`),
KEY `other_key` (`other`))
ENGINE="FEDERATED" DEFAULT CHARSET=latin1 ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
...@@ -181,15 +160,109 @@ INSERT INTO federated.t1 (name, other) VALUES ('Ninth Name', 99999); ...@@ -181,15 +160,109 @@ INSERT INTO federated.t1 (name, other) VALUES ('Ninth Name', 99999);
INSERT INTO federated.t1 (name, other) VALUES ('Tenth Name', 101010); INSERT INTO federated.t1 (name, other) VALUES ('Tenth Name', 101010);
# basic select # basic select
EXPLAIN SELECT * FROM federated.t1;
SELECT * FROM federated.t1;
# with PRIMARY KEY index_read_idx
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5;
SELECT * FROM federated.t1 WHERE id = 5;
EXPLAIN SELECT * FROM federated.t1 WHERE name = 'Sixth Name';
SELECT * FROM federated.t1 WHERE name = 'Sixth Name';
EXPLAIN SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
EXPLAIN SELECT * FROM federated.t1 WHERE name = 'Sixth Name' AND other = 44444;
SELECT * FROM federated.t1 WHERE name = 'Sixth Name' AND other = 44444;
EXPLAIN SELECT * FROM federated.t1 WHERE name like '%th%';
SELECT * FROM federated.t1 WHERE name like '%th%';
UPDATE federated.t1 SET name = '3rd name' WHERE id = 3;
SELECT * FROM federated.t1 WHERE name = '3rd name';
UPDATE federated.t1 SET name = 'Third name' WHERE name = '3rd name';
SELECT * FROM federated.t1 WHERE name = 'Third name';
# rnd_post, ::position
EXPLAIN SELECT * FROM federated.t1 ORDER BY id DESC;
SELECT * FROM federated.t1 ORDER BY id DESC;
EXPLAIN SELECT * FROM federated.t1 ORDER BY name;
SELECT * FROM federated.t1 ORDER BY name;
EXPLAIN SELECT * FROM federated.t1 ORDER BY name DESC;
SELECT * FROM federated.t1 ORDER BY name DESC;
EXPLAIN SELECT * FROM federated.t1 ORDER BY name ASC;
SELECT * FROM federated.t1 ORDER BY name ASC;
EXPLAIN SELECT * FROM federated.t1 GROUP BY other;
SELECT * FROM federated.t1 GROUP BY other;
# ::delete_row
DELETE FROM federated.t1 WHERE id = 5;
SELECT * FROM federated.t1 WHERE id = 5;
# ::delete_all_rows
DELETE FROM federated.t1;
SELECT * FROM federated.t1 WHERE id = 5;
# previous test, but this time with indexes
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment,
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime NOT NULL,
PRIMARY KEY (`id`),
key name(`name`),
key other(`other`),
key created(`created`))
DEFAULT CHARSET=latin1;
connection master;
DROP TABLE IF EXISTS federated.t1;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment,
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime NOT NULL,
PRIMARY KEY (`id`),
key name(`name`),
key other(`other`),
key created(`created`))
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
INSERT INTO federated.t1 (name, other, created)
VALUES ('First Name', 11111, '2004-01-01 01:01:01');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Second Name', 22222, '2004-01-23 02:43:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Third Name', 33333, '2004-02-14 02:14:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Fourth Name', 44444, '2003-04-05 00:00:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Fifth Name', 55555, '2001-02-02 02:02:02');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Sixth Name', 66666, '2005-06-06 15:30:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Seventh Name', 77777, '2003-12-12 18:32:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Eigth Name', 88888, '2005-03-12 11:00:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Ninth Name', 99999, '2005-03-12 11:00:01');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Tenth Name', 101010, '2005-03-12 12:00:01');
# basic select
EXPLAIN SELECT * FROM federated.t1;
SELECT * FROM federated.t1; SELECT * FROM federated.t1;
# with PRIMARY KEY index_read_idx # with PRIMARY KEY index_read_idx
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5;
SELECT * FROM federated.t1 WHERE id = 5; SELECT * FROM federated.t1 WHERE id = 5;
# with regular key index_read -> index_read_idx # with regular key index_read -> index_read_idx
EXPLAIN SELECT * FROM federated.t1 WHERE name = 'Sixth Name';
SELECT * FROM federated.t1 WHERE name = 'Sixth Name'; SELECT * FROM federated.t1 WHERE name = 'Sixth Name';
# regular and PRIMARY KEY index_read_idx # regular and PRIMARY KEY index_read_idx
EXPLAIN SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name'; SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
# with regular key index_read -> index_read_idx # with regular key index_read -> index_read_idx
EXPLAIN SELECT * FROM federated.t1 WHERE other = 44444;
SELECT * FROM federated.t1 WHERE other = 44444; SELECT * FROM federated.t1 WHERE other = 44444;
EXPLAIN SELECT * FROM federated.t1 WHERE name like '%th%';
SELECT * FROM federated.t1 WHERE name like '%th%'; SELECT * FROM federated.t1 WHERE name like '%th%';
# update - update_row, index_read_idx # update - update_row, index_read_idx
UPDATE federated.t1 SET name = '3rd name' WHERE id = 3; UPDATE federated.t1 SET name = '3rd name' WHERE id = 3;
...@@ -211,7 +284,6 @@ SELECT * FROM federated.t1 WHERE id = 5; ...@@ -211,7 +284,6 @@ SELECT * FROM federated.t1 WHERE id = 5;
# ::delete_all_rows # ::delete_all_rows
DELETE FROM federated.t1; DELETE FROM federated.t1;
SELECT * FROM federated.t1 WHERE id = 5; SELECT * FROM federated.t1 WHERE id = 5;
connection slave; connection slave;
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 ( CREATE TABLE federated.t1 (
...@@ -253,8 +325,7 @@ SET name = 'Fourth Name', other = 'four four four' ...@@ -253,8 +325,7 @@ SET name = 'Fourth Name', other = 'four four four'
WHERE name IS NULL AND other IS NULL; WHERE name IS NULL AND other IS NULL;
UPDATE federated.t1 SET other = 'two two two two' WHERE name = 'Second Name'; UPDATE federated.t1 SET other = 'two two two two' WHERE name = 'Second Name';
UPDATE federated.t1 SET other = 'seven seven' WHERE name like 'Sec%'; UPDATE federated.t1 SET other = 'seven seven' WHERE name like 'Sev%';
UPDATE federated.t1 SET other = 'seven seven' WHERE name = 'Seventh Name';
UPDATE federated.t1 SET name = 'Tenth Name' WHERE other like 'fee fie%'; UPDATE federated.t1 SET name = 'Tenth Name' WHERE other like 'fee fie%';
SELECT * FROM federated.t1 WHERE name IS NULL OR other IS NULL ; SELECT * FROM federated.t1 WHERE name IS NULL OR other IS NULL ;
SELECT * FROM federated.t1; SELECT * FROM federated.t1;
...@@ -338,6 +409,272 @@ SELECT * FROM federated.t1 WHERE name='third'; ...@@ -338,6 +409,272 @@ SELECT * FROM federated.t1 WHERE name='third';
SELECT * FROM federated.t1 WHERE other=2222; SELECT * FROM federated.t1 WHERE other=2222;
SELECT * FROM federated.t1 WHERE name='third' and other=2222; SELECT * FROM federated.t1 WHERE name='third' and other=2222;
# more multi-column indexes, in the primary key
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int NOT NULL auto_increment,
`col1` int(10) NOT NULL DEFAULT 0,
`col2` varchar(64) NOT NULL DEFAULT '',
`col3` int(20) NOT NULL,
`col4` int(40) NOT NULL,
primary key (`id`, `col1`, `col2`, `col3`, `col4`),
key col1(col1),
key col2(col2),
key col3(col3),
key col4(col4));
connection master;
DROP TABLE IF EXISTS federated.t1;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (
`id` int NOT NULL auto_increment,
`col1` int(10) NOT NULL DEFAULT 0,
`col2` varchar(64) NOT NULL DEFAULT '',
`col3` int(20) NOT NULL,
`col4` int(40) NOT NULL,
primary key (`id`, `col1`, `col2`, `col3`, `col4`),
key col1(col1),
key col2(col2),
key col3(col3),
key col4(col4))
ENGINE="FEDERATED"
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (1, 'one One', 11, 1111);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (2, 'Two two', 22, 2222);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (3, 'three Three', 33, 33333);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (4, 'fourfourfour', 444, 4444444);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (5, 'five 5 five five 5', 5, 55555);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (6, 'six six Sixsix', 6666, 6);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (7, 'seven Sevenseven', 77777, 7777);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (8, 'eight eight eight', 88888, 88);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (9, 'nine Nine', 999999, 999999);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (10, 'Tenth ten TEN', 1010101, 1010);
EXPLAIN SELECT * FROM federated.t1 WHERE col2 = 'two two';
SELECT * FROM federated.t1 WHERE col2 = 'two two';
EXPLAIN SELECT * FROM federated.t1 WHERE col2 = 'two Two';
SELECT * FROM federated.t1 WHERE col2 = 'two Two';
SELECT * FROM federated.t1 WHERE id = 3;
EXPLAIN SELECT * FROM federated.t1 WHERE id = 3;
SELECT * FROM federated.t1 WHERE id = 3 AND col1 = 3;
EXPLAIN SELECT * FROM federated.t1 WHERE id = 3 AND col1 = 3;
SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'Two two';
EXPLAIN SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'Two two';
SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'fourfourfour';
EXPLAIN SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'fourfourfour';
SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5;
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5;
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5
AND col4 = 55555;
SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5
AND col4 = 55555;
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'Two two' AND col3 = 22
AND col4 = 33;
SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'Two two' AND col3 = 22
AND col4 = 33;
EXPLAIN SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'five 5 five five 5' AND col3 = 5
AND col4 = 55555;
SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'five 5 five five 5' AND col3 = 5
AND col4 = 55555;
EXPLAIN SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'five 5 five five 5')
OR (col2 = 'three Three' AND col3 = 33);
SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'five 5 five five 5')
OR (col2 = 'three Three' AND col3 = 33);
EXPLAIN SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'five 5 five five 5')
OR (col2 = 'three Three' AND col3 = 33)
OR col4 = 1010;
SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'five 5 five five 5')
OR (col2 = 'three Three' AND col3 = 33)
OR col4 = 1010;
EXPLAIN SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'Two two')
OR (col2 = 444 AND col3 = 4444444);
SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'Two two')
OR (col2 = 444 AND col3 = 4444444);
EXPLAIN SELECT * FROM federated.t1 WHERE id = 1
OR col1 = 10
OR col2 = 'Two two'
OR col3 = 33
OR col4 = 4444444;
SELECT * FROM federated.t1 WHERE id = 1
OR col1 = 10
OR col2 = 'Two two'
OR col3 = 33
OR col4 = 4444444;
EXPLAIN SELECT * FROM federated.t1 WHERE id > 5;
SELECT * FROM federated.t1 WHERE id > 5;
EXPLAIN SELECT * FROM federated.t1 WHERE id >= 5;
SELECT * FROM federated.t1 WHERE id >= 5;
EXPLAIN SELECT * FROM federated.t1 WHERE id < 5;
SELECT * FROM federated.t1 WHERE id < 5;
EXPLAIN SELECT * FROM federated.t1 WHERE id <= 5;
SELECT * FROM federated.t1 WHERE id <= 5;
EXPLAIN SELECT * FROM federated.t1 WHERE id != 5;
SELECT * FROM federated.t1 WHERE id != 5;
EXPLAIN SELECT * FROM federated.t1 WHERE id > 3 AND id < 7;
SELECT * FROM federated.t1 WHERE id > 3 AND id < 7;
EXPLAIN SELECT * FROM federated.t1 WHERE id > 3 AND id <= 7;
SELECT * FROM federated.t1 WHERE id > 3 AND id <= 7;
EXPLAIN SELECT * FROM federated.t1 WHERE id >= 3 AND id <= 7;
SELECT * FROM federated.t1 WHERE id >= 3 AND id <= 7;
EXPLAIN SELECT * FROM federated.t1 WHERE id < 3 AND id <= 7;
SELECT * FROM federated.t1 WHERE id < 3 AND id <= 7;
EXPLAIN SELECT * FROM federated.t1 WHERE id < 3 AND id > 7;
SELECT * FROM federated.t1 WHERE id < 3 AND id > 7;
EXPLAIN SELECT * FROM federated.t1 WHERE id < 3 OR id > 7;
SELECT * FROM federated.t1 WHERE id < 3 OR id > 7;
EXPLAIN SELECT * FROM federated.t1 WHERE col2 = 'three Three';
SELECT * FROM federated.t1 WHERE col2 = 'three Three';
EXPLAIN SELECT * FROM federated.t1 WHERE col2 > 'one';
SELECT * FROM federated.t1 WHERE col2 > 'one';
EXPLAIN SELECT * FROM federated.t1 WHERE col2 LIKE 's%';
SELECT * FROM federated.t1 WHERE col2 LIKE 's%';
EXPLAIN SELECT * FROM federated.t1 WHERE col2 LIKE 'si%';
SELECT * FROM federated.t1 WHERE col2 LIKE 'si%';
EXPLAIN SELECT * FROM federated.t1 WHERE col2 LIKE 'se%';
SELECT * FROM federated.t1 WHERE col2 LIKE 'se%';
EXPLAIN SELECT * FROM federated.t1 WHERE col2 NOT LIKE 'e%';
SELECT * FROM federated.t1 WHERE col2 NOT LIKE 'e%';
EXPLAIN SELECT * FROM federated.t1 WHERE col2 <> 'one One';
SELECT * FROM federated.t1 WHERE col2 <> 'one One';
# more multi-column indexes, in the primary key
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(128) NOT NULL DEFAULT '',
`col3` varchar(20) NOT NULL DEFAULT '',
`col4` varchar(40) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`, `col4`),
key 3key(`col2`,`col3`,`col4`),
key 2key (`col3`,`col4`),
key col4(col4));
connection master;
DROP TABLE IF EXISTS federated.t1;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(128) NOT NULL DEFAULT '',
`col3` varchar(20) NOT NULL DEFAULT '',
`col4` varchar(40) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`, `col4`),
key 3key(`col2`,`col3`,`col4`),
key 2key (`col3`,`col4`),
key col4(col4))
ENGINE="FEDERATED"
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('aaaa', 'aaaaaaaaaaaaaaaaaaa', 'ababababab', 'acacacacacacacac');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('bbbb', 'bbbbbbbbbbbbbbbbbbb', 'bababababa', 'bcbcbcbcbcbcbcbc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('cccc', 'ccccccccccccccccccc', 'cacacacaca', 'cbcbcbcbcbcbcbcb');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('dddd', 'ddddddddddddddddddd', 'dadadadada', 'dcdcdcdcdcdcdcdc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('eeee', 'eeeeeeeeeeeeeeeeeee', 'eaeaeaeaea', 'ecececececececec');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('ffff', 'fffffffffffffffffff', 'fafafafafa', 'fcfcfcfcfcfcfcfc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('gggg', 'ggggggggggggggggggg', 'gagagagaga', 'gcgcgcgcgcgcgcgc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('hhhh', 'hhhhhhhhhhhhhhhhhhh', 'hahahahaha', 'hchchchchchchchc');
EXPLAIN SELECT * FROM federated.t1 WHERE col1 = 'cccc';
SELECT * FROM federated.t1 WHERE col1 = 'cccc';
EXPLAIN SELECT * FROM federated.t1 WHERE col2 = 'eeeeeeeeeeeeeeeeeee';
SELECT * FROM federated.t1 WHERE col2 = 'eeeeeeeeeeeeeeeeeee';
EXPLAIN SELECT * FROM federated.t1 WHERE col3 = 'bababababa';
SELECT * FROM federated.t1 WHERE col3 = 'bababababa';
EXPLAIN SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col2 = 'ggggggggggggggggggg';
SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col2 = 'ggggggggggggggggggg';
EXPLAIN SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col3 = 'gagagagaga';
SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col3 = 'gagagagaga';
EXPLAIN SELECT * FROM federated.t1 WHERE col1 = 'ffff' AND col4 = 'fcfcfcfcfcfcfcfc';
SELECT * FROM federated.t1 WHERE col1 = 'ffff' AND col4 = 'fcfcfcfcfcfcfcfc';
EXPLAIN SELECT * FROM federated.t1 WHERE col1 > 'bbbb';
SELECT * FROM federated.t1 WHERE col1 > 'bbbb';
EXPLAIN SELECT * FROM federated.t1 WHERE col1 >= 'bbbb';
SELECT * FROM federated.t1 WHERE col1 >= 'bbbb';
EXPLAIN SELECT * FROM federated.t1 WHERE col1 < 'bbbb';
SELECT * FROM federated.t1 WHERE col1 < 'bbbb';
EXPLAIN SELECT * FROM federated.t1 WHERE col1 <= 'bbbb';
SELECT * FROM federated.t1 WHERE col1 <= 'bbbb';
EXPLAIN SELECT * FROM federated.t1 WHERE col1 <> 'bbbb';
SELECT * FROM federated.t1 WHERE col1 <> 'bbbb';
EXPLAIN SELECT * FROM federated.t1 WHERE col1 LIKE 'b%';
SELECT * FROM federated.t1 WHERE col1 LIKE 'b%';
EXPLAIN SELECT * FROM federated.t1 WHERE col4 LIKE '%b%';
SELECT * FROM federated.t1 WHERE col4 LIKE '%b%';
EXPLAIN SELECT * FROM federated.t1 WHERE col1 NOT LIKE 'c%';
SELECT * FROM federated.t1 WHERE col1 NOT LIKE 'c%';
EXPLAIN SELECT * FROM federated.t1 WHERE col4 NOT LIKE '%c%';
SELECT * FROM federated.t1 WHERE col4 NOT LIKE '%c%';
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` int(8) NOT NULL DEFAULT 0,
`col3` varchar(8) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`));
connection master;
DROP TABLE IF EXISTS federated.t1;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(8) NOT NULL DEFAULT '',
`col3` varchar(8) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`))
ENGINE="FEDERATED"
DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
INSERT INTO federated.t1 VALUES ('a00', '110', 'cc0');
INSERT INTO federated.t1 VALUES ('aaa', '111', 'ccc');
INSERT INTO federated.t1 VALUES ('bbb', '222', 'yyy');
INSERT INTO federated.t1 VALUES ('ccc', '111', 'zzz');
INSERT INTO federated.t1 VALUES ('ccd', '112', 'zzzz');
# let's see what the foreign database says
connection slave;
EXPLAIN SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
connection master;
EXPLAIN SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
# test NULLs # test NULLs
connection slave; connection slave;
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
...@@ -374,6 +711,11 @@ WHERE id IS NULL ...@@ -374,6 +711,11 @@ WHERE id IS NULL
AND name IS NULL AND name IS NULL
AND floatval IS NULL AND floatval IS NULL
AND other IS NULL; AND other IS NULL;
EXPLAIN SELECT count(*) FROM federated.t1
WHERE id IS NULL
AND name IS NULL
AND floatval IS NULL
AND other IS NULL;
connection slave; connection slave;
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
...@@ -735,6 +1077,7 @@ values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...@@ -735,6 +1077,7 @@ values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "PatrickG"); 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "PatrickG");
UPDATE federated.t1 SET b=repeat('a',256); UPDATE federated.t1 SET b=repeat('a',256);
UPDATE federated.t1 SET i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0, i10=0; UPDATE federated.t1 SET i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0, i10=0;
EXPLAIN SELECT * FROM federated.t1 WHERE i9=0 and i10=0;
SELECT * FROM federated.t1 WHERE i9=0 and i10=0; SELECT * FROM federated.t1 WHERE i9=0 and i10=0;
UPDATE federated.t1 SET i50=20; UPDATE federated.t1 SET i50=20;
SELECT * FROM federated.t1; SELECT * FROM federated.t1;
...@@ -928,14 +1271,4 @@ ORDER BY federated.t1.country_id; ...@@ -928,14 +1271,4 @@ ORDER BY federated.t1.country_id;
DROP TABLE federated.countries; DROP TABLE federated.countries;
connection master; source include/federated_cleanup.inc;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
connection slave;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
***IMPORTANT*** ***IMPORTANT***
This is a first release, conceptual release
Only 'mysql://' is supported at this release. Only 'mysql://' is supported at this release.
...@@ -345,6 +346,7 @@ ...@@ -345,6 +346,7 @@
*/ */
#define FEDERATED_DEBUG 1
#include "mysql_priv.h" #include "mysql_priv.h"
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
...@@ -352,7 +354,8 @@ ...@@ -352,7 +354,8 @@
#ifdef HAVE_FEDERATED_DB #ifdef HAVE_FEDERATED_DB
#include "ha_federated.h" #include "ha_federated.h"
#define MAX_REMOTE_SIZE IO_SIZE
#include "m_string.h"
/* Variables for federated share methods */ /* Variables for federated share methods */
static HASH federated_open_tables; // Hash used to track open static HASH federated_open_tables; // Hash used to track open
// tables // tables
...@@ -413,13 +416,14 @@ bool federated_db_end() ...@@ -413,13 +416,14 @@ bool federated_db_end()
return FALSE; return FALSE;
} }
/* /*
Check (in create) whether the tables exists, and that it can be connected to Check (in create) whether the tables exists, and that it can be connected to
SYNOPSIS SYNOPSIS
check_foreign_data_source() check_foreign_data_source()
share pointer to FEDERATED share share pointer to FEDERATED share
table_create_flag tells us that ::create is the caller,
therefore, return CANT_CREATE_FEDERATED_TABLE
DESCRIPTION DESCRIPTION
This method first checks that the connection information that parse url This method first checks that the connection information that parse url
...@@ -427,23 +431,24 @@ bool federated_db_end() ...@@ -427,23 +431,24 @@ bool federated_db_end()
table, and if so, does the foreign table exist. table, and if so, does the foreign table exist.
*/ */
static int check_foreign_data_source(FEDERATED_SHARE *share) static int check_foreign_data_source(
FEDERATED_SHARE *share,
bool table_create_flag)
{ {
char escaped_table_base_name[IO_SIZE]; char escaped_table_name[STRING_BUFFER_USUAL_SIZE];
MYSQL *mysql; char query_buffer[FEDERATED_QUERY_BUFFER_SIZE];
MYSQL_RES *result=0; char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
uint error_code; uint error_code;
char query_buffer[IO_SIZE];
char error_buffer[IO_SIZE];
String query(query_buffer, sizeof(query_buffer), &my_charset_bin); String query(query_buffer, sizeof(query_buffer), &my_charset_bin);
MYSQL_RES *result= 0;
MYSQL *mysql;
DBUG_ENTER("ha_federated::check_foreign_data_source"); DBUG_ENTER("ha_federated::check_foreign_data_source");
/* Zero the length, otherwise the string will have misc chars */
query.length(0); query.length(0);
/* error out if we can't alloc memory for mysql_init(NULL) (per Georg) */ /* error out if we can't alloc memory for mysql_init(NULL) (per Georg) */
if (! (mysql= mysql_init(NULL))) if (! (mysql= mysql_init(NULL)))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
/* check if we can connect */ /* check if we can connect */
if (!mysql_real_connect(mysql, if (!mysql_real_connect(mysql,
share->hostname, share->hostname,
...@@ -453,11 +458,17 @@ static int check_foreign_data_source(FEDERATED_SHARE *share) ...@@ -453,11 +458,17 @@ static int check_foreign_data_source(FEDERATED_SHARE *share)
share->port, share->port,
share->socket, 0)) share->socket, 0))
{ {
/*
we want the correct error message, but it to return
ER_CANT_CREATE_FEDERATED_TABLE if called by ::create
*/
error_code= table_create_flag?
ER_CANT_CREATE_FEDERATED_TABLE : ER_CONNECT_TO_FOREIGN_DATA_SRC;
my_sprintf(error_buffer, my_sprintf(error_buffer,
(error_buffer, (error_buffer, " database %s username %s hostname %s",
"unable to connect to database '%s' on host '%s as user '%s' !", share->database, share->username, share->hostname));
share->database, share->hostname, share->username)); my_error(ER_CONNECT_TO_FOREIGN_DATA_SRC, MYF(0), error_buffer);
error_code= ER_CONNECT_TO_MASTER;
goto error; goto error;
} }
else else
...@@ -468,48 +479,41 @@ static int check_foreign_data_source(FEDERATED_SHARE *share) ...@@ -468,48 +479,41 @@ static int check_foreign_data_source(FEDERATED_SHARE *share)
with transactions with transactions
*/ */
mysql->reconnect= 1; mysql->reconnect= 1;
/* /*
Note: I am not using INORMATION_SCHEMA because this needs to work with < 5.0 Note: I am not using INORMATION_SCHEMA because this needs to work with < 5.0
if we can connect, then make sure the table exists if we can connect, then make sure the table exists
*/ */
query.append("SHOW TABLES LIKE '"); query.append("SELECT * FROM `", 15);
escape_string_for_mysql(&my_charset_bin, (char *)escaped_table_base_name, escape_string_for_mysql(&my_charset_bin, (char *)escaped_table_name,
sizeof(escaped_table_base_name), sizeof(escaped_table_name),
share->table_base_name, share->table_name,
share->table_base_name_length); share->table_name_length);
query.append(escaped_table_base_name); query.append(escaped_table_name);
query.append("'"); query.append("` WHERE 1=0", 11);
error_code= ER_QUERY_ON_MASTER;
if (mysql_real_query(mysql, query.ptr(), query.length()))
goto error;
result= mysql_store_result(mysql); /*
if (! result) an || here on the error code - if it's a syntax error, or missing
goto error; table, give us that, or if the connection has problems, give us that
*/
/* if ! mysql_num_rows, the table doesn't exist, send error */ if (mysql_real_query(mysql, query.ptr(), query.length()))
if (! mysql_num_rows(result))
{ {
my_sprintf(error_buffer, error_code= table_create_flag ?
(error_buffer, "foreign table '%s' does not exist!", ER_CANT_CREATE_FEDERATED_TABLE : ER_FOREIGN_DATA_SRC_DOESNT_EXIST;
share->table_base_name)); my_sprintf(error_buffer, (error_buffer, ": %d : %s",
mysql_errno(mysql), mysql_error(mysql)));
my_error(error_code, MYF(0), error_buffer);
goto error; goto error;
} }
mysql_free_result(result);
result= 0;
mysql_close(mysql); mysql_close(mysql);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
error: error:
if (result)
mysql_free_result(result);
mysql_close(mysql); mysql_close(mysql);
my_error(error_code, MYF(0), error_buffer);
DBUG_RETURN(error_code); DBUG_RETURN(error_code);
} }
...@@ -545,22 +549,27 @@ error: ...@@ -545,22 +549,27 @@ error:
'password' and 'port' are both optional. 'password' and 'port' are both optional.
RETURN VALUE RETURN VALUE
0 success 0 success
1 failure, wrong string format error_num particular error code
*/ */
static int parse_url(FEDERATED_SHARE *share, TABLE *table, static int parse_url(FEDERATED_SHARE *share, TABLE *table,
uint table_create_flag) uint table_create_flag)
{ {
uint error_num= (table_create_flag ? ER_CANT_CREATE_TABLE : uint error_num= (table_create_flag ?
ER_CONNECT_TO_MASTER); ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE :
ER_FOREIGN_DATA_STRING_INVALID);
DBUG_ENTER("ha_federated::parse_url"); DBUG_ENTER("ha_federated::parse_url");
share->port= 0; share->port= 0;
share->socket= 0;
share->scheme= my_strdup(table->s->comment, MYF(0)); share->scheme= my_strdup(table->s->comment, MYF(0));
DBUG_PRINT("info",("parse_url alloced share->scheme %lx", share->scheme));
/*
remove addition of null terminator and store length
for each string in share
*/
if ((share->username= strstr(share->scheme, "://"))) if ((share->username= strstr(share->scheme, "://")))
{ {
share->scheme[share->username - share->scheme]= '\0'; share->scheme[share->username - share->scheme]= '\0';
...@@ -613,20 +622,20 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, ...@@ -613,20 +622,20 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
share->port= atoi(share->sport); share->port= atoi(share->sport);
} }
if ((share->table_base_name= strchr(share->database, '/'))) if ((share->table_name= strchr(share->database, '/')))
{ {
share->database[share->table_base_name - share->database]= '\0'; share->database[share->table_name - share->database]= '\0';
share->table_base_name++; share->table_name++;
} }
else else
goto error; goto error;
share->table_base_name_length= strlen(share->table_base_name); share->table_name_length= strlen(share->table_name);
} }
else else
goto error; goto error;
/* make sure there's not an extra / */ /* make sure there's not an extra / */
if ((strchr(share->table_base_name, '/'))) if ((strchr(share->table_name, '/')))
goto error; goto error;
if (share->hostname[0] == '\0') if (share->hostname[0] == '\0')
...@@ -645,7 +654,7 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, ...@@ -645,7 +654,7 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
hostname %s port %d database %s tablename %s\n", hostname %s port %d database %s tablename %s\n",
share->scheme, share->username, share->password, share->scheme, share->username, share->password,
share->hostname, share->port, share->database, share->hostname, share->port, share->database,
share->table_base_name)); share->table_name));
} }
else else
goto error; goto error;
...@@ -656,9 +665,16 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, ...@@ -656,9 +665,16 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
DBUG_RETURN(0); DBUG_RETURN(0);
error: error:
my_error(error_num, MYF(0), if (share->scheme)
"connection string is not in the correct format",0); {
DBUG_RETURN(1); DBUG_PRINT("info",
("error: parse_url. Returning error code %d \
freeing share->scheme %lx", error_num, share->scheme));
my_free((gptr) share->scheme, MYF(0));
share->scheme= 0;
}
my_error(error_num, MYF(0), table->s->comment);
DBUG_RETURN(error_num);
} }
...@@ -684,9 +700,9 @@ error: ...@@ -684,9 +700,9 @@ error:
uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row) uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row)
{ {
ulong *lengths;
uint num_fields; uint num_fields;
uint x= 0; ulong *lengths;
Field **field;
DBUG_ENTER("ha_federated::convert_row_to_internal_format"); DBUG_ENTER("ha_federated::convert_row_to_internal_format");
...@@ -695,14 +711,105 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row) ...@@ -695,14 +711,105 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row)
memset(record, 0, table->s->null_bytes); memset(record, 0, table->s->null_bytes);
for (Field **field= table->field; *field; field++, x++) for (field= table->field; *field; field++)
{ {
/*
index variable to move us through the row at the
same iterative step as the field
*/
int x= field - table->field;
my_ptrdiff_t old_ptr;
old_ptr= (my_ptrdiff_t) (record - table->record[0]);
(*field)->move_field(old_ptr);
if (!row[x]) if (!row[x])
(*field)->set_null(); (*field)->set_null();
else else
{
(*field)->set_notnull();
(*field)->store(row[x], lengths[x], &my_charset_bin); (*field)->store(row[x], lengths[x], &my_charset_bin);
}
(*field)->move_field(-old_ptr);
} }
DBUG_DUMP("record", record, table->s->reclength);
DBUG_RETURN(0);
}
static bool emit_key_part_name(String *to, KEY_PART_INFO *part)
{
DBUG_ENTER("emit_key_part_name");
if (to->append(" `", 2) ||
to->append(part->field->field_name) ||
to->append("`", 1))
DBUG_RETURN(1); // Out of memory
DBUG_RETURN(0);
}
static bool emit_key_part_element(String *to, KEY_PART_INFO *part,
bool needs_quotes, bool is_like,
const byte *ptr, uint len)
{
Field *field= part->field;
DBUG_ENTER("emit_key_part_element");
if (needs_quotes && to->append("'", 1))
DBUG_RETURN(1);
if (part->type == HA_KEYTYPE_BIT)
{
char buff[STRING_BUFFER_USUAL_SIZE], *buf= buff;
*buf++= '0';
*buf++= 'x';
for (; len; ptr++,len--)
{
uint tmp= (uint)(uchar) *ptr;
*buf++= _dig_vec_upper[tmp >> 4];
*buf++= _dig_vec_upper[tmp & 15];
}
if (to->append(buff, (uint)(buf - buff)))
DBUG_RETURN(1);
}
else if (part->key_part_flag & HA_BLOB_PART)
{
String blob;
uint blob_length= uint2korr(ptr);
blob.set_quick((char*) ptr+HA_KEY_BLOB_LENGTH,
blob_length, &my_charset_bin);
if (append_escaped(to, &blob))
DBUG_RETURN(1);
}
else if (part->key_part_flag & HA_VAR_LENGTH_PART)
{
String varchar;
uint var_length= uint2korr(ptr);
varchar.set_quick((char*) ptr+HA_KEY_BLOB_LENGTH,
var_length, &my_charset_bin);
if (append_escaped(to, &varchar))
DBUG_RETURN(1);
}
else
{
char strbuff[MAX_FIELD_WIDTH];
String str(strbuff, sizeof(strbuff), part->field->charset()), *res;
res= field->val_str(&str, (char *)ptr);
if (field->result_type() == STRING_RESULT)
{
if (append_escaped(to, res))
DBUG_RETURN(1);
}
else if (to->append(res->ptr(), res->length()))
DBUG_RETURN(1);
}
if (is_like && to->append("%", 1))
DBUG_RETURN(1);
if (needs_quotes && to->append("'",1))
DBUG_RETURN(1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -716,6 +823,8 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row) ...@@ -716,6 +823,8 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row)
key_info KEY struct pointer key_info KEY struct pointer
key byte pointer containing key key byte pointer containing key
key_length length of key key_length length of key
range_type 0 - no range, 1 - min range, 2 - max range
(see enum range_operation)
DESCRIPTION DESCRIPTION
Using iteration through all the keys via a KEY_PART_INFO pointer, Using iteration through all the keys via a KEY_PART_INFO pointer,
...@@ -726,112 +835,391 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row) ...@@ -726,112 +835,391 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row)
0 After all keys have been accounted for to create the WHERE clause 0 After all keys have been accounted for to create the WHERE clause
1 No keys found 1 No keys found
*/ Range flags Table per Timour:
-----------------
- start_key:
* ">" -> HA_READ_AFTER_KEY
* ">=" -> HA_READ_KEY_OR_NEXT
* "=" -> HA_READ_KEY_EXACT
- end_key:
* "<" -> HA_READ_BEFORE_KEY
* "<=" -> HA_READ_AFTER_KEY
records_in_range:
-----------------
- start_key:
* ">" -> HA_READ_AFTER_KEY
* ">=" -> HA_READ_KEY_EXACT
* "=" -> HA_READ_KEY_EXACT
- end_key:
* "<" -> HA_READ_BEFORE_KEY
* "<=" -> HA_READ_AFTER_KEY
* "=" -> HA_READ_AFTER_KEY
bool ha_federated::create_where_from_key(String *to, KEY *key_info, 0 HA_READ_KEY_EXACT, Find first record else error
const byte *key, uint key_length) 1 HA_READ_KEY_OR_NEXT, Record or next record
2 HA_READ_KEY_OR_PREV, Record or previous
3 HA_READ_AFTER_KEY, Find next rec. after key-record
4 HA_READ_BEFORE_KEY, Find next rec. before key-record
5 HA_READ_PREFIX, Key which as same prefix
6 HA_READ_PREFIX_LAST, Last key with the same prefix
7 HA_READ_PREFIX_LAST_OR_PREV, Last or prev key with the same prefix
Flags that I've found:
id, primary key, varchar
id = 'ccccc'
records_in_range: start_key 0 end_key 3
read_range_first: start_key 0 end_key NULL
id > 'ccccc'
records_in_range: start_key 3 end_key NULL
read_range_first: start_key 3 end_key NULL
id < 'ccccc'
records_in_range: start_key NULL end_key 4
read_range_first: start_key NULL end_key 4
id <= 'ccccc'
records_in_range: start_key NULL end_key 3
read_range_first: start_key NULL end_key 3
id >= 'ccccc'
records_in_range: start_key 0 end_key NULL
read_range_first: start_key 1 end_key NULL
id like 'cc%cc'
records_in_range: start_key 0 end_key 3
read_range_first: start_key 1 end_key 3
id > 'aaaaa' and id < 'ccccc'
records_in_range: start_key 3 end_key 4
read_range_first: start_key 3 end_key 4
id >= 'aaaaa' and id < 'ccccc';
records_in_range: start_key 0 end_key 4
read_range_first: start_key 1 end_key 4
id >= 'aaaaa' and id <= 'ccccc';
records_in_range: start_key 0 end_key 3
read_range_first: start_key 1 end_key 3
id > 'aaaaa' and id <= 'ccccc';
records_in_range: start_key 3 end_key 3
read_range_first: start_key 3 end_key 3
numeric keys:
id = 4
index_read_idx: start_key 0 end_key NULL
id > 4
records_in_range: start_key 3 end_key NULL
read_range_first: start_key 3 end_key NULL
id >= 4
records_in_range: start_key 0 end_key NULL
read_range_first: start_key 1 end_key NULL
id < 4
records_in_range: start_key NULL end_key 4
read_range_first: start_key NULL end_key 4
id <= 4
records_in_range: start_key NULL end_key 3
read_range_first: start_key NULL end_key 3
id like 4
full table scan, select * from
id > 2 and id < 8
records_in_range: start_key 3 end_key 4
read_range_first: start_key 3 end_key 4
id >= 2 and id < 8
records_in_range: start_key 0 end_key 4
read_range_first: start_key 1 end_key 4
id >= 2 and id <= 8
records_in_range: start_key 0 end_key 3
read_range_first: start_key 1 end_key 3
id > 2 and id <= 8
records_in_range: start_key 3 end_key 3
read_range_first: start_key 3 end_key 3
multi keys (id int, name varchar, other varchar)
id = 1;
records_in_range: start_key 0 end_key 3
read_range_first: start_key 0 end_key NULL
id > 4;
id > 2 and name = '333'; remote: id > 2
id > 2 and name > '333'; remote: id > 2
id > 2 and name > '333' and other < 'ddd'; remote: id > 2 no results
id > 2 and name >= '333' and other < 'ddd'; remote: id > 2 1 result
id >= 4 and name = 'eric was here' and other > 'eeee';
records_in_range: start_key 3 end_key NULL
read_range_first: start_key 3 end_key NULL
id >= 4;
id >= 2 and name = '333' and other < 'ddd';
remote: `id` >= 2 AND `name` >= '333';
records_in_range: start_key 0 end_key NULL
read_range_first: start_key 1 end_key NULL
id < 4;
id < 3 and name = '222' and other <= 'ccc'; remote: id < 3
records_in_range: start_key NULL end_key 4
read_range_first: start_key NULL end_key 4
id <= 4;
records_in_range: start_key NULL end_key 3
read_range_first: start_key NULL end_key 3
id like 4;
full table scan
id > 2 and id < 4;
records_in_range: start_key 3 end_key 4
read_range_first: start_key 3 end_key 4
id >= 2 and id < 4;
records_in_range: start_key 0 end_key 4
read_range_first: start_key 1 end_key 4
id >= 2 and id <= 4;
records_in_range: start_key 0 end_key 3
read_range_first: start_key 1 end_key 3
id > 2 and id <= 4;
id = 6 and name = 'eric was here' and other > 'eeee';
remote: (`id` > 6 AND `name` > 'eric was here' AND `other` > 'eeee')
AND (`id` <= 6) AND ( AND `name` <= 'eric was here')
no results
records_in_range: start_key 3 end_key 3
read_range_first: start_key 3 end_key 3
Summary:
* If the start key flag is 0 the max key flag shouldn't even be set,
and if it is, the query produced would be invalid.
* Multipart keys, even if containing some or all numeric columns,
are treated the same as non-numeric keys
If the query is " = " (quotes or not):
- records in range start key flag HA_READ_KEY_EXACT,
end key flag HA_READ_AFTER_KEY (incorrect)
- any other: start key flag HA_READ_KEY_OR_NEXT,
end key flag HA_READ_AFTER_KEY (correct)
* 'like' queries (of key)
- Numeric, full table scan
- Non-numeric
records_in_range: start_key 0 end_key 3
other : start_key 1 end_key 3
* If the key flag is HA_READ_AFTER_KEY:
if start_key, append >
if end_key, append <=
* If create_where_key was called by records_in_range:
- if the key is numeric:
start key flag is 0 when end key is NULL, end key flag is 3 or 4
- if create_where_key was called by any other function:
start key flag is 1 when end key is NULL, end key flag is 3 or 4
- if the key is non-numeric, or multipart
When the query is an exact match, the start key flag is 0,
end key flag is 3 for what should be a no-range condition where
you should have 0 and max key NULL, which it is if called by
read_range_first
Conclusion:
1. Need logic to determin if a key is min or max when the flag is
HA_READ_AFTER_KEY, and handle appending correct operator accordingly
2. Need a boolean flag to pass to create_where_from_key, used in the
switch statement. Add 1 to the flag if:
- start key flag is HA_READ_KEY_EXACT and the end key is NULL
*/
bool ha_federated::create_where_from_key(String *to,
KEY *key_info,
const key_range *start_key,
const key_range *end_key,
bool records_in_range)
{ {
uint second_loop= 0; bool both_not_null= (start_key != NULL && end_key != NULL) ? TRUE : FALSE;
KEY_PART_INFO *key_part; const byte *ptr;
bool needs_quotes; uint remainder, length;
String tmp; char tmpbuff[FEDERATED_QUERY_BUFFER_SIZE];
String tmp(tmpbuff, sizeof(tmpbuff), system_charset_info);
const key_range *ranges[2]= { start_key, end_key };
DBUG_ENTER("ha_federated::create_where_from_key"); DBUG_ENTER("ha_federated::create_where_from_key");
for (key_part= key_info->key_part; (int) key_length > 0; key_part++) tmp.length(0);
{ if (start_key == NULL && end_key == NULL)
Field *field= key_part->field; DBUG_RETURN(1);
needs_quotes= field->needs_quotes();
uint length= key_part->length;
if (second_loop++ && to->append(" AND ", 5)) for (int i= 0; i <= 1; i++)
DBUG_RETURN(1); {
if (to->append('`') || to->append(field->field_name) || to->append("` ", 2)) bool needs_quotes;
DBUG_RETURN(1); // Out of memory uint loop_counter= 0;
KEY_PART_INFO *key_part;
if (ranges[i] == NULL)
continue;
const byte *key= ranges[i]->key;
uint key_length= ranges[i]->length;
if (key_part->null_bit) if (both_not_null)
{ {
if (*key++) if (i > 0)
{ tmp.append(") AND (", 7);
if (to->append("IS NULL", 7)) else
DBUG_RETURN(1); tmp.append("(", 1);
DBUG_PRINT("info",
("NULL type %s", to->c_ptr_quick()));
key_length-= key_part->store_length;
key+= key_part->store_length - 1;
continue;
}
key_length--;
} }
if (to->append("= "))
DBUG_RETURN(1);
if (needs_quotes && to->append("'"))
DBUG_RETURN(1);
if (key_part->type == HA_KEYTYPE_BIT)
{
/* This is can be treated as a hex string */
Field_bit *field= (Field_bit *) (key_part->field);
char buff[64 + 2], *ptr;
byte *end= (byte*)(key)+length;
buff[0]= '0';
buff[1]= 'x';
for (ptr= buff + 2; key < end; key++)
{
uint tmp= (uint)(uchar) *key;
*ptr++= _dig_vec_upper[tmp >> 4];
*ptr++= _dig_vec_upper[tmp & 15];
}
if (to->append(buff, (uint)(ptr - buff)))
DBUG_RETURN(1);
key_length-= length; for (key_part= key_info->key_part,
continue; remainder= key_info->key_parts,
} length= ranges[i]->length,
if (key_part->key_part_flag & HA_BLOB_PART) ptr= ranges[i]->key; ;
remainder--,
key_part++)
{ {
uint blob_length= uint2korr(key); Field *field= key_part->field;
key+= HA_KEY_BLOB_LENGTH; uint store_length= key_part->store_length;
key_length-= HA_KEY_BLOB_LENGTH; uint part_length= min(store_length, length);
needs_quotes= field->needs_quotes();
DBUG_DUMP("key, start of loop", (char *) ptr, length);
tmp.set_quick((char*) key, blob_length, &my_charset_bin); if (key_part->null_bit)
if (append_escaped(to, &tmp)) {
DBUG_RETURN(1); if (*ptr++)
{
if (emit_key_part_name(&tmp, key_part) ||
tmp.append(" IS NULL", 8))
DBUG_RETURN(1);
continue;
}
}
length= key_part->length; if (tmp.append("(", 1))
}
else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
{
length= uint2korr(key);
key+= HA_KEY_BLOB_LENGTH;
tmp.set_quick((char*) key, length, &my_charset_bin);
if (append_escaped(to, &tmp))
DBUG_RETURN(1); DBUG_RETURN(1);
}
else
{
char buff[MAX_FIELD_WIDTH];
String str(buff, sizeof(buff), field->charset()), *res;
res= field->val_str(&str, (char*) (key)); switch(ranges[i]->flag) {
if (field->result_type() == STRING_RESULT) case(HA_READ_KEY_EXACT):
{ if (store_length >= length ||
if (append_escaped(to, res)) !needs_quotes ||
key_part->type == HA_KEYTYPE_BIT ||
field->result_type() != STRING_RESULT)
{
if (emit_key_part_name(&tmp, key_part))
DBUG_RETURN(1);
if (records_in_range)
{
if (tmp.append(" >= ", 4))
DBUG_RETURN(1);
}
else
{
if (tmp.append(" = ", 3))
DBUG_RETURN(1);
}
if (emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
DBUG_RETURN(1);
}
else
/* LIKE */
{
if (emit_key_part_name(&tmp, key_part) ||
tmp.append(" LIKE ", 6) ||
emit_key_part_element(&tmp, key_part, needs_quotes, 1, ptr,
part_length))
DBUG_RETURN(1);
}
break;
case(HA_READ_AFTER_KEY):
if (store_length >= length) /* end key */
{
if (emit_key_part_name(&tmp, key_part))
DBUG_RETURN(1);
if (i > 0) /* end key */
tmp.append(" <= ", 4);
else /* start key */
tmp.append(" > ", 3);
if (emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
DBUG_RETURN(1);
break;
}
case(HA_READ_KEY_OR_NEXT):
if ( emit_key_part_name(&tmp, key_part) ||
tmp.append(" >= ", 4) ||
emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
DBUG_RETURN(1);
break;
case(HA_READ_BEFORE_KEY):
if (store_length >= length)
{
if (emit_key_part_name(&tmp, key_part) ||
tmp.append(" < ", 3) ||
emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
DBUG_RETURN(1);
break;
}
case(HA_READ_KEY_OR_PREV):
if ( emit_key_part_name(&tmp, key_part) ||
tmp.append(" <= ", 4) ||
emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
DBUG_RETURN(1); DBUG_RETURN(1);
res= field->val_str(&str, (char*) (key)); break;
default:
DBUG_PRINT("info",("cannot handle flag %d", ranges[i]->flag));
DBUG_RETURN(1);
} }
else if (to->append(res->ptr(), res->length())) if (tmp.append(")", 1))
DBUG_RETURN(1); DBUG_RETURN(1);
next_loop:
if (store_length >= length)
break;
DBUG_PRINT("info", ("remainder %d", remainder));
DBUG_ASSERT(remainder > 1);
length-= store_length;
ptr+= store_length;
if (tmp.append(" AND ", 5))
DBUG_RETURN(1);
DBUG_PRINT("info",
("create_where_from_key WHERE clause: %s",
tmp.c_ptr_quick()));
} }
if (needs_quotes && to->append("'"))
DBUG_RETURN(1);
DBUG_PRINT("info",
("final value for 'to' %s", to->c_ptr_quick()));
key+= length;
key_length-= length;
DBUG_RETURN(0);
} }
DBUG_RETURN(1); if (both_not_null)
tmp.append(")", 1);
if (to->append(" WHERE ", 7))
DBUG_RETURN(1);
if (to->append(tmp))
DBUG_RETURN(1);
DBUG_RETURN(0);
} }
/* /*
...@@ -842,40 +1230,45 @@ bool ha_federated::create_where_from_key(String *to, KEY *key_info, ...@@ -842,40 +1230,45 @@ bool ha_federated::create_where_from_key(String *to, KEY *key_info,
static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
{ {
FEDERATED_SHARE *share; char *select_query, *tmp_table_name;
char query_buffer[IO_SIZE]; char query_buffer[FEDERATED_QUERY_BUFFER_SIZE];
uint tmp_table_name_length;
Field **field;
String query(query_buffer, sizeof(query_buffer), &my_charset_bin); String query(query_buffer, sizeof(query_buffer), &my_charset_bin);
FEDERATED_SHARE *share;
/*
In order to use this string, we must first zero it's length,
or it will contain garbage
*/
query.length(0); query.length(0);
uint table_name_length, table_base_name_length;
char *tmp_table_name, *table_base_name, *select_query;
/* share->table_name has the file location - we want the table's name! */
table_base_name= (char*) table->s->table_name;
DBUG_PRINT("info", ("table_name %s", table_base_name));
/*
So why does this exist? There is no way currently to init a storage engine.
Innodb and BDB both have modifications to the server to allow them to
do this. Since you will not want to do this, this is probably the next
best method.
*/
pthread_mutex_lock(&federated_mutex); pthread_mutex_lock(&federated_mutex);
table_name_length= (uint) strlen(table_name); tmp_table_name= (char *)table->s->table_name;
table_base_name_length= (uint) strlen(table_base_name); tmp_table_name_length= (uint) strlen(tmp_table_name);
if (!(share= (FEDERATED_SHARE *) hash_search(&federated_open_tables, if (!(share= (FEDERATED_SHARE *) hash_search(&federated_open_tables,
(byte*) table_name, (byte*) table_name,
table_name_length))) strlen(table_name))))
{ {
query.set_charset(system_charset_info); query.set_charset(system_charset_info);
query.append("SELECT * FROM `"); query.append("SELECT ", 7);
for (field= table->field; *field; field++)
{
query.append("`", 1);
query.append((*field)->field_name);
query.append("`,", 2);
}
query.length(query.length()-1);
query.append(" FROM `", 7);
if (!(share= (FEDERATED_SHARE *) if (!(share= (FEDERATED_SHARE *)
my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), my_multi_malloc(MYF(MY_WME),
&share, sizeof(*share), &share, sizeof(*share),
&tmp_table_name, table_name_length + 1, &tmp_table_name, tmp_table_name_length+ 1,
&select_query, query.length() + &select_query,
strlen(table->s->comment) + 1, NullS))) query.length()+strlen(table->s->comment)+1,
NullS)))
{ {
pthread_mutex_unlock(&federated_mutex); pthread_mutex_unlock(&federated_mutex);
return NULL; return NULL;
...@@ -884,16 +1277,15 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) ...@@ -884,16 +1277,15 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
if (parse_url(share, table, 0)) if (parse_url(share, table, 0))
goto error; goto error;
query.append(share->table_base_name); query.append(share->table_name, share->table_name_length);
query.append("`"); query.append("`", 1);
share->use_count= 0;
share->table_name_length= table_name_length;
share->table_name= tmp_table_name;
share->select_query= select_query; share->select_query= select_query;
strmov(share->table_name, table_name);
strmov(share->select_query, query.ptr()); strmov(share->select_query, query.ptr());
share->use_count= 0;
share->table_name_length= strlen(share->table_name);
DBUG_PRINT("info", DBUG_PRINT("info",
("share->select_query %s", share->select_query)); ("share->select_query %s", share->select_query));
if (my_hash_insert(&federated_open_tables, (byte*) share)) if (my_hash_insert(&federated_open_tables, (byte*) share))
goto error; goto error;
thr_lock_init(&share->lock); thr_lock_init(&share->lock);
...@@ -907,9 +1299,13 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) ...@@ -907,9 +1299,13 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
error: error:
pthread_mutex_unlock(&federated_mutex); pthread_mutex_unlock(&federated_mutex);
if (share->scheme) if (share->scheme)
{
DBUG_PRINT("info",
("error: get_share. Freeing share->scheme %lx",
share->scheme));
my_free((gptr) share->scheme, MYF(0)); my_free((gptr) share->scheme, MYF(0));
my_free((gptr) share, MYF(0)); share->scheme= 0;
}
return NULL; return NULL;
} }
...@@ -922,12 +1318,19 @@ error: ...@@ -922,12 +1318,19 @@ error:
static int free_share(FEDERATED_SHARE *share) static int free_share(FEDERATED_SHARE *share)
{ {
DBUG_ENTER("free_share");
pthread_mutex_lock(&federated_mutex); pthread_mutex_lock(&federated_mutex);
if (!--share->use_count) if (!--share->use_count)
{ {
if (share->scheme) if (share->scheme)
{
DBUG_PRINT("info",
("free_share: Freeing share->scheme %lx",
share->scheme));
my_free((gptr) share->scheme, MYF(0)); my_free((gptr) share->scheme, MYF(0));
share->scheme= 0;
}
hash_delete(&federated_open_tables, (byte*) share); hash_delete(&federated_open_tables, (byte*) share);
thr_lock_delete(&share->lock); thr_lock_delete(&share->lock);
...@@ -936,23 +1339,109 @@ static int free_share(FEDERATED_SHARE *share) ...@@ -936,23 +1339,109 @@ static int free_share(FEDERATED_SHARE *share)
} }
pthread_mutex_unlock(&federated_mutex); pthread_mutex_unlock(&federated_mutex);
return 0; DBUG_RETURN(0);
} }
ha_rows ha_federated::records_in_range(uint inx, key_range *start_key,
key_range *end_key)
{
/*
const byte *key;
uint length;
enum ha_rkey_function flag;
Note:
records_in_range should sent to the remote an explain
'select * from table where ...' start_key and end_key
The job of this is to give a reasonable estimate of how many rows
a query will produce, not precise, just general to help the optimiser
choose an optimal query plan - this function MUST be QUICK!
USE Explain to get row estimate. Do not use count.
Should this method even be here? We really want indexes to be used as often
as possible, therefore it seems we just need to hard-code the return value
to a very low number
*/
#ifdef CALC_RECORDS_IN_RANGE
char sql_query_buf[FEDERATED_QUERY_BUFFER_SIZE];
int error= 0;
ha_rows return_rows= 20;
String sql_query(sql_query_buf, sizeof(sql_query_buf), &my_charset_bin);
MYSQL_RES *result= 0;
MYSQL_ROW row;
#endif
DBUG_ENTER("ha_federated::records_in_range");
#ifdef CALC_RECORDS_IN_RANGE
if (start_key == NULL && end_key == NULL)
DBUG_RETURN(0);
sql_query.length(0);
sql_query.append("EXPLAIN ", 8);
sql_query.append(share->select_query);
create_where_from_key(&sql_query,
&table->key_info[inx],
start_key,
end_key,
1);
DBUG_PRINT("info",("inx %d sql_query %s", inx, sql_query.c_ptr_quick()));
if (mysql_real_query(mysql, sql_query.ptr(), sql_query.length()))
goto error;
sql_query.length(0);
result= mysql_store_result(mysql);
if (! result)
goto error;
if (! mysql_num_rows(result))
goto error;
if (!(row= mysql_fetch_row(result)))
goto error;
if (! row[8])
return_rows=0;
else
return_rows= (ha_rows) my_strtoll10(row[8], (char**) 0, &error);
if (result)
{
mysql_free_result(result);
result= 0;
}
error:
if (result)
{
mysql_free_result(result);
result= 0;
}
DBUG_PRINT("info", ("return_rows (records) %d", return_rows));
DBUG_RETURN(return_rows);
#else
DBUG_RETURN(FEDERATED_RECORDS_IN_RANGE);
#endif
}
/* /*
If frm_error() is called then we will use this to to find out If frm_error() is called then we will use this to to find out
what file extentions exist for the storage engine. This is what file extentions exist for the storage engine. This is
also used by the default rename_table and delete_table method also used by the default rename_table and delete_table method
in handler.cc. in handler.cc.
*/ */
static const char *ha_federated_exts[] = {
NullS
};
const char **ha_federated::bas_ext() const const char **ha_federated::bas_ext() const
{ {
return ha_federated_exts; static const char *ext[]=
{
NullS
};
return ext;
} }
...@@ -969,6 +1458,7 @@ const char **ha_federated::bas_ext() const ...@@ -969,6 +1458,7 @@ const char **ha_federated::bas_ext() const
int ha_federated::open(const char *name, int mode, uint test_if_locked) int ha_federated::open(const char *name, int mode, uint test_if_locked)
{ {
int rc;
DBUG_ENTER("ha_federated::open"); DBUG_ENTER("ha_federated::open");
if (!(share= get_share(name, table))) if (!(share= get_share(name, table)))
...@@ -990,8 +1480,13 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked) ...@@ -990,8 +1480,13 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
share->port, share->port,
share->socket, 0)) share->socket, 0))
{ {
my_error(ER_CONNECT_TO_MASTER, MYF(0), mysql_error(mysql)); int error_code;
DBUG_RETURN(ER_CONNECT_TO_MASTER); char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
error_code= ER_CONNECT_TO_FOREIGN_DATA_SRC;
my_sprintf(error_buffer, (error_buffer, ": %d : %s",
mysql_errno(mysql), mysql_error(mysql)));
my_error(error_code, MYF(0), error_buffer);
DBUG_RETURN(error_code);
} }
/* /*
Since we do not support transactions at this version, we can let the client Since we do not support transactions at this version, we can let the client
...@@ -1016,6 +1511,7 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked) ...@@ -1016,6 +1511,7 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
int ha_federated::close(void) int ha_federated::close(void)
{ {
int retval;
DBUG_ENTER("ha_federated::close"); DBUG_ENTER("ha_federated::close");
/* free the result set */ /* free the result set */
...@@ -1028,7 +1524,8 @@ int ha_federated::close(void) ...@@ -1028,7 +1524,8 @@ int ha_federated::close(void)
} }
/* Disconnect from mysql */ /* Disconnect from mysql */
mysql_close(mysql); mysql_close(mysql);
DBUG_RETURN(free_share(share)); retval= free_share(share);
DBUG_RETURN(retval);
} }
...@@ -1085,30 +1582,34 @@ inline uint field_in_record_is_null(TABLE *table, ...@@ -1085,30 +1582,34 @@ inline uint field_in_record_is_null(TABLE *table,
int ha_federated::write_row(byte *buf) int ha_federated::write_row(byte *buf)
{ {
uint x= 0, num_fields= 0; bool num_fields;
Field **field; int error_code;
query_id_t current_query_id= 1;
ulong tmp_query_id= 1;
uint all_fields_have_same_query_id= 1; uint all_fields_have_same_query_id= 1;
ulong current_query_id= 1;
char insert_buffer[IO_SIZE]; ulong tmp_query_id= 1;
char values_buffer[IO_SIZE], insert_field_value_buffer[IO_SIZE]; char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char insert_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char values_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char insert_field_value_buffer[STRING_BUFFER_USUAL_SIZE];
Field **field;
/* The main insert query string */ /* The main insert query string */
String insert_string(insert_buffer, sizeof(insert_buffer), &my_charset_bin); String insert_string(insert_buffer, sizeof(insert_buffer), &my_charset_bin);
insert_string.length(0);
/* The string containing the values to be added to the insert */ /* The string containing the values to be added to the insert */
String values_string(values_buffer, sizeof(values_buffer), &my_charset_bin); String values_string(values_buffer, sizeof(values_buffer), &my_charset_bin);
values_string.length(0);
/* The actual value of the field, to be added to the values_string */ /* The actual value of the field, to be added to the values_string */
String insert_field_value_string(insert_field_value_buffer, String insert_field_value_string(insert_field_value_buffer,
sizeof(insert_field_value_buffer), sizeof(insert_field_value_buffer),
&my_charset_bin); &my_charset_bin);
values_string.length(0);
insert_string.length(0);
insert_field_value_string.length(0); insert_field_value_string.length(0);
DBUG_ENTER("ha_federated::write_row"); DBUG_ENTER("ha_federated::write_row");
DBUG_PRINT("info", ("table charset name %s csname %s", DBUG_PRINT("info",
table->s->table_charset->name, table->s->table_charset->csname)); ("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); statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
...@@ -1123,21 +1624,22 @@ int ha_federated::write_row(byte *buf) ...@@ -1123,21 +1624,22 @@ int ha_federated::write_row(byte *buf)
DBUG_PRINT("info", ("current query id %d", current_query_id)); DBUG_PRINT("info", ("current query id %d", current_query_id));
/* start off our string */ /* start off our string */
insert_string.append("INSERT INTO `"); insert_string.append("INSERT INTO `", 13);
insert_string.append(share->table_base_name); insert_string.append(share->table_name, share->table_name_length);
insert_string.append("`"); insert_string.append("`",1);
/* start both our field and field values strings */ /* start both our field and field values strings */
insert_string.append(" ("); insert_string.append(" (", 2);
values_string.append(" VALUES ("); values_string.append(" VALUES (", 9);
/* /*
Even if one field is different, all_fields_same_query_id can't remain 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 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) such as in the case of INSERT INTO table VALUES (val1, val2, valN)
*/ */
for (field= table->field; *field; field++, x++) for (field= table->field; *field; field++)
{ {
if (x > 0 && tmp_query_id != (*field)->query_id) if (field > table->field && tmp_query_id != (*field)->query_id)
all_fields_have_same_query_id= 0; all_fields_have_same_query_id= 0;
tmp_query_id= (*field)->query_id; tmp_query_id= (*field)->query_id;
...@@ -1145,31 +1647,30 @@ int ha_federated::write_row(byte *buf) ...@@ -1145,31 +1647,30 @@ int ha_federated::write_row(byte *buf)
/* /*
loop through the field pointer array, add any fields to both the values loop through the field pointer array, add any fields to both the values
list and the fields list that match the current query id list and the fields list that match the current query id
You might ask "Why an index variable (num_fields) ?" My answer is that
we need to count how many fields we actually need
*/ */
x=0; for (field= table->field; *field; field++)
for (field= table->field; *field; field++, x++)
{ {
/* if there is a query id and if it's equal to the current query id */ /* 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) if (((*field)->query_id && (*field)->query_id == current_query_id)
|| all_fields_have_same_query_id) || all_fields_have_same_query_id)
{ {
num_fields++; /*
There are some fields. This will be used later to determine
whether to chop off commas and parens.
*/
num_fields= TRUE;
if ((*field)->is_null()) if ((*field)->is_null())
{ insert_field_value_string.append("NULL", 4);
DBUG_PRINT("info",
("column %d current query id %d field is_null query id %d",
x, current_query_id, (*field)->query_id));
insert_field_value_string.append("NULL");
}
else else
{ {
DBUG_PRINT("info",
("column %d current query id %d field is not null query ID %d",
x, current_query_id, (*field)->query_id));
(*field)->val_str(&insert_field_value_string); (*field)->val_str(&insert_field_value_string);
/* quote these fields if they require it */ /* quote these fields if they require it */
(*field)->quote_data(&insert_field_value_string); } (*field)->quote_data(&insert_field_value_string);
}
/* append the field name */ /* append the field name */
insert_string.append((*field)->field_name); insert_string.append((*field)->field_name);
...@@ -1178,8 +1679,15 @@ int ha_federated::write_row(byte *buf) ...@@ -1178,8 +1679,15 @@ int ha_federated::write_row(byte *buf)
insert_field_value_string.length(0); insert_field_value_string.length(0);
/* append commas between both fields and fieldnames */ /* append commas between both fields and fieldnames */
insert_string.append(','); /*
values_string.append(','); 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(",",1);
values_string.append(",",1);
} }
} }
...@@ -1197,15 +1705,14 @@ int ha_federated::write_row(byte *buf) ...@@ -1197,15 +1705,14 @@ int ha_federated::write_row(byte *buf)
AND, we don't want to chop off the last char '(' AND, we don't want to chop off the last char '('
insert will be "INSERT INTO t1 VALUES ();" insert will be "INSERT INTO t1 VALUES ();"
*/ */
DBUG_PRINT("info", ("x %d num fields %d", x, num_fields)); if (num_fields)
if (num_fields > 0)
{ {
/* chops off leading commas */ /* chops off leading commas */
values_string.chop(); values_string.chop();
insert_string.append(')'); insert_string.append(")", 1);
} }
/* we always want to append this, even if there aren't any fields */ /* we always want to append this, even if there aren't any fields */
values_string.append(')'); values_string.append(")", 1);
/* add the values */ /* add the values */
insert_string.append(values_string); insert_string.append(values_string);
...@@ -1214,8 +1721,11 @@ int ha_federated::write_row(byte *buf) ...@@ -1214,8 +1721,11 @@ int ha_federated::write_row(byte *buf)
if (mysql_real_query(mysql, insert_string.ptr(), insert_string.length())) if (mysql_real_query(mysql, insert_string.ptr(), insert_string.length()))
{ {
my_error(ER_QUERY_ON_MASTER, MYF(0), mysql_error(mysql)); error_code= ER_QUERY_ON_FOREIGN_DATA_SRC;
DBUG_RETURN(ER_QUERY_ON_MASTER); my_sprintf(error_buffer, (error_buffer, ": %d : %s",
mysql_errno(mysql), mysql_error(mysql)));
my_error(error_code, MYF(0), error_buffer);
DBUG_RETURN(error_code);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -1241,39 +1751,56 @@ int ha_federated::write_row(byte *buf) ...@@ -1241,39 +1751,56 @@ int ha_federated::write_row(byte *buf)
int ha_federated::update_row(const byte *old_data, byte *new_data) int ha_federated::update_row(const byte *old_data, byte *new_data)
{ {
uint x= 0; /*
uint has_a_primary_key= 0; This used to control how the query was built. If there was a primary key,
uint primary_key_field_num; the query would be built such that there was a where clause with only
char old_field_value_buffer[IO_SIZE], new_field_value_buffer[IO_SIZE]; that column as the condition. This is flawed, because if we have a multi-part
char update_buffer[IO_SIZE], where_buffer[IO_SIZE]; primary key, it would only use the first part! We don't need to do this anyway,
because read_range_first will retrieve the correct record, which is what is used
to build the WHERE clause. We can however use this to append a LIMIT to the end
if there is NOT a primary key. Why do this? Because we only are updating one
record, and LIMIT enforces this.
*/
bool has_a_primary_key= (table->s->primary_key == 0 ? TRUE : FALSE);
/*
buffers for following strings
*/
char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char old_field_value_buffer[STRING_BUFFER_USUAL_SIZE];
char new_field_value_buffer[STRING_BUFFER_USUAL_SIZE];
char update_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char where_buffer[FEDERATED_QUERY_BUFFER_SIZE];
/* stores the value to be replaced of the field were are updating */ /* stores the value to be replaced of the field were are updating */
String old_field_value(old_field_value_buffer, sizeof(old_field_value_buffer), String old_field_value(old_field_value_buffer,
sizeof(old_field_value_buffer),
&my_charset_bin); &my_charset_bin);
/* stores the new value of the field */ /* stores the new value of the field */
String new_field_value(new_field_value_buffer, sizeof(new_field_value_buffer), String new_field_value(new_field_value_buffer,
sizeof(new_field_value_buffer),
&my_charset_bin); &my_charset_bin);
/* stores the update query */ /* stores the update query */
String update_string(update_buffer, sizeof(update_buffer), &my_charset_bin); String update_string(update_buffer,
sizeof(update_buffer),
&my_charset_bin);
/* stores the WHERE clause */ /* stores the WHERE clause */
String where_string(where_buffer, sizeof(where_buffer), &my_charset_bin); String where_string(where_buffer,
sizeof(where_buffer),
&my_charset_bin);
DBUG_ENTER("ha_federated::update_row"); DBUG_ENTER("ha_federated::update_row");
/*
set string lengths to 0 to avoid misc chars in string
*/
old_field_value.length(0); old_field_value.length(0);
new_field_value.length(0); new_field_value.length(0);
update_string.length(0); update_string.length(0);
where_string.length(0); where_string.length(0);
has_a_primary_key= (table->s->primary_key == 0 ? 1 : 0); update_string.append("UPDATE `", 8);
primary_key_field_num= has_a_primary_key ? update_string.append(share->table_name);
table->key_info[table->s->primary_key].key_part->fieldnr - 1 : -1; update_string.append("`", 1);
if (has_a_primary_key) update_string.append(" SET ", 5);
DBUG_PRINT("info", ("has a primary key"));
update_string.append("UPDATE `");
update_string.append(share->table_base_name);
update_string.append("`");
update_string.append(" SET ");
/* /*
In this loop, we want to match column names to values being inserted In this loop, we want to match column names to values being inserted
...@@ -1285,104 +1812,73 @@ int ha_federated::update_row(const byte *old_data, byte *new_data) ...@@ -1285,104 +1812,73 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
field=oldvalue field=oldvalue
*/ */
for (Field **field= table->field; *field; field++, x++) for (Field **field= table->field; *field; field++)
{ {
/* where_string.append((*field)->field_name);
In all of these tests for 'has_a_primary_key', what I'm trying to
accomplish is to only use the primary key in the WHERE clause if the
table has a primary key, as opposed to a table without a primary key
in which case we have to use all the fields to create a WHERE clause
using the old/current values, as well as adding a LIMIT statement
*/
if (has_a_primary_key)
{
if (x == primary_key_field_num)
where_string.append((*field)->field_name);
}
else
where_string.append((*field)->field_name);
update_string.append((*field)->field_name); update_string.append((*field)->field_name);
update_string.append('='); update_string.append(" = ", 3);
if ((*field)->is_null()) if ((*field)->is_null())
{ new_field_value.append("NULL", 4);
DBUG_PRINT("info", ("column %d is NULL", x ));
new_field_value.append("NULL");
}
else else
{ {
/* otherwise = */ /* otherwise = */
(*field)->val_str(&new_field_value); (*field)->val_str(&new_field_value);
(*field)->quote_data(&new_field_value); (*field)->quote_data(&new_field_value);
if (has_a_primary_key) if (!field_in_record_is_null(table, *field, (char*) old_data))
{ where_string.append(" = ", 3);
if (x == primary_key_field_num)
where_string.append("=");
}
else if (!field_in_record_is_null(table, *field, (char*) old_data))
where_string.append("=");
} }
if (has_a_primary_key) if (field_in_record_is_null(table, *field, (char*) old_data))
{ where_string.append(" IS NULL ", 9);
if (x == primary_key_field_num)
{
(*field)->val_str(&old_field_value,
(char*) (old_data + (*field)->offset()));
(*field)->quote_data(&old_field_value);
where_string.append(old_field_value);
}
}
else else
{ {
if (field_in_record_is_null(table, *field, (char*) old_data)) uint o_len;
where_string.append(" IS NULL "); (*field)->val_str(&old_field_value,
else (char*) (old_data + (*field)->offset()));
{ o_len= (*field)->pack_length();
uint o_len; (*field)->quote_data(&old_field_value);
(*field)->val_str(&old_field_value, where_string.append(old_field_value);
(char*) (old_data + (*field)->offset()));
o_len= (*field)->pack_length();
DBUG_PRINT("info", ("o_len %lu", o_len));
(*field)->quote_data(&old_field_value);
where_string.append(old_field_value);
}
} }
DBUG_PRINT("info",
("column %d new value %s old value %s",
x, new_field_value.c_ptr_quick(), old_field_value.c_ptr_quick() ));
update_string.append(new_field_value); update_string.append(new_field_value);
new_field_value.length(0); new_field_value.length(0);
if (x + 1 < table->s->fields) /*
Only append conjunctions if we have another field in which
to iterate
*/
if (*(field + 1))
{ {
update_string.append(", "); update_string.append(", ", 2);
if (!has_a_primary_key) where_string.append(" AND ", 5);
where_string.append(" AND ");
} }
old_field_value.length(0); old_field_value.length(0);
} }
update_string.append(" WHERE "); update_string.append(" WHERE ", 7);
update_string.append(where_string); update_string.append(where_string);
/*
If this table has not a primary key, then we could possibly
update multiple rows. We want to make sure to only update one!
*/
if (! has_a_primary_key) if (! has_a_primary_key)
update_string.append(" LIMIT 1"); update_string.append(" LIMIT 1", 8);
DBUG_PRINT("info", ("Final update query: %s",
update_string.c_ptr_quick()));
if (mysql_real_query(mysql, update_string.ptr(), update_string.length())) if (mysql_real_query(mysql, update_string.ptr(), update_string.length()))
{ {
my_error(ER_QUERY_ON_MASTER, MYF(0), mysql_error(mysql)); int error_code= ER_QUERY_ON_FOREIGN_DATA_SRC;
DBUG_RETURN(ER_QUERY_ON_MASTER); char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
my_sprintf(error_buffer, (error_buffer, ": %d : %s",
mysql_errno(mysql), mysql_error(mysql)));
my_error(error_code, MYF(0), error_buffer);
DBUG_RETURN(error_code);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* /*
This will delete a row. 'buf' will contain a copy of the row to be deleted. This will delete a row. 'buf' will contain a copy of the row to be =deleted.
The server will call this right after the current row has been called (from The server will call this right after the current row has been called (from
either a previous rnd_nexT() or index call). either a previous rnd_nexT() or index call).
If you keep a pointer to the last row or can access a primary key it will If you keep a pointer to the last row or can access a primary key it will
...@@ -1398,49 +1894,59 @@ int ha_federated::update_row(const byte *old_data, byte *new_data) ...@@ -1398,49 +1894,59 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
int ha_federated::delete_row(const byte *buf) int ha_federated::delete_row(const byte *buf)
{ {
char delete_buffer[IO_SIZE]; char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char data_buffer[IO_SIZE]; char delete_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char data_buffer[FEDERATED_QUERY_BUFFER_SIZE];
String delete_string(delete_buffer, sizeof(delete_buffer), &my_charset_bin); String delete_string(delete_buffer, sizeof(delete_buffer), &my_charset_bin);
String data_string(data_buffer, sizeof(data_buffer), &my_charset_bin); String data_string(data_buffer, sizeof(data_buffer), &my_charset_bin);
delete_string.length(0);
data_string.length(0);
DBUG_ENTER("ha_federated::delete_row"); DBUG_ENTER("ha_federated::delete_row");
delete_string.length(0); delete_string.append("DELETE FROM `", 13);
delete_string.append("DELETE FROM `"); delete_string.append(share->table_name);
delete_string.append(share->table_base_name); delete_string.append("`", 1);
delete_string.append("`"); delete_string.append(" WHERE ", 7);
delete_string.append(" WHERE ");
for (Field **field= table->field; *field; field++) for (Field **field= table->field; *field; field++)
{ {
Field *cur_field= *field; delete_string.append((*field)->field_name);
data_string.length(0);
delete_string.append(cur_field->field_name);
if (cur_field->is_null_in_record((const uchar*) buf)) if ((*field)->is_null())
{ {
delete_string.append(" IS "); delete_string.append(" IS ", 4);
data_string.append("NULL"); data_string.append("NULL", 4);
} }
else else
{ {
delete_string.append("="); delete_string.append(" = ", 3);
cur_field->val_str(&data_string, (char*) buf+ cur_field->offset()); (*field)->val_str(&data_string);
cur_field->quote_data(&data_string); (*field)->quote_data(&data_string);
} }
delete_string.append(data_string); delete_string.append(data_string);
delete_string.append(" AND "); data_string.length(0);
if (*(field + 1))
delete_string.append(" AND ", 5);
} }
delete_string.length(delete_string.length()-5); // Remove AND delete_string.append(" LIMIT 1", 8);
delete_string.append(" LIMIT 1");
DBUG_PRINT("info", DBUG_PRINT("info",
("Delete sql: %s", delete_string.c_ptr_quick())); ("Delete sql: %s", delete_string.c_ptr_quick()));
if (mysql_real_query(mysql, delete_string.ptr(), delete_string.length())) if (mysql_real_query(mysql, delete_string.ptr(), delete_string.length()))
{ {
my_error(ER_QUERY_ON_MASTER, MYF(0), mysql_error(mysql)); int error_code= ER_QUERY_ON_FOREIGN_DATA_SRC;
DBUG_RETURN(ER_QUERY_ON_MASTER); char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
my_error(error_code, MYF(0), error_buffer);
DBUG_RETURN(error_code);
} }
deleted+= mysql->affected_rows;
DBUG_PRINT("info",
("rows deleted %d rows deleted for all time %d",
int(mysql->affected_rows), deleted));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -1454,12 +1960,12 @@ int ha_federated::delete_row(const byte *buf) ...@@ -1454,12 +1960,12 @@ int ha_federated::delete_row(const byte *buf)
*/ */
int ha_federated::index_read(byte *buf, const byte *key, int ha_federated::index_read(byte *buf, const byte *key,
uint key_len __attribute__ ((unused)), uint key_len, enum ha_rkey_function find_flag)
enum ha_rkey_function find_flag
__attribute__ ((unused)))
{ {
int retval;
DBUG_ENTER("ha_federated::index_read"); DBUG_ENTER("ha_federated::index_read");
DBUG_RETURN(index_read_idx(buf, active_index, key, key_len, find_flag)); retval= index_read_idx(buf, active_index, key, key_len, find_flag);
DBUG_RETURN(retval);
} }
...@@ -1473,17 +1979,23 @@ int ha_federated::index_read(byte *buf, const byte *key, ...@@ -1473,17 +1979,23 @@ int ha_federated::index_read(byte *buf, const byte *key,
*/ */
int ha_federated::index_read_idx(byte *buf, uint index, const byte *key, int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
uint key_len __attribute__ ((unused)), uint key_len, enum ha_rkey_function find_flag)
enum ha_rkey_function find_flag
__attribute__ ((unused)))
{ {
char index_value[IO_SIZE]; int retval;
String index_string(index_value, sizeof(index_value), &my_charset_bin); char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
index_string.length(0); char index_value[STRING_BUFFER_USUAL_SIZE];
uint keylen; char key_value[STRING_BUFFER_USUAL_SIZE];
char test_value[STRING_BUFFER_USUAL_SIZE];
char sql_query_buffer[FEDERATED_QUERY_BUFFER_SIZE];
String index_string(index_value,
sizeof(index_value),
&my_charset_bin);
String sql_query(sql_query_buffer,
sizeof(sql_query_buffer),
&my_charset_bin);
key_range range;
char sql_query_buffer[IO_SIZE]; index_string.length(0);
String sql_query(sql_query_buffer, sizeof(sql_query_buffer), &my_charset_bin);
sql_query.length(0); sql_query.length(0);
DBUG_ENTER("ha_federated::index_read_idx"); DBUG_ENTER("ha_federated::index_read_idx");
...@@ -1492,10 +2004,14 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key, ...@@ -1492,10 +2004,14 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
&LOCK_status); &LOCK_status);
sql_query.append(share->select_query); sql_query.append(share->select_query);
sql_query.append(" WHERE ");
keylen= strlen((char*) (key)); range.key= key;
create_where_from_key(&index_string, &table->key_info[index], key, keylen); range.length= key_len;
range.flag= find_flag;
create_where_from_key(&index_string,
&table->key_info[index],
&range,
NULL, NULL);
sql_query.append(index_string); sql_query.append(index_string);
DBUG_PRINT("info", DBUG_PRINT("info",
...@@ -1514,35 +2030,43 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key, ...@@ -1514,35 +2030,43 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
} }
if (mysql_real_query(mysql, sql_query.ptr(), sql_query.length())) if (mysql_real_query(mysql, sql_query.ptr(), sql_query.length()))
{ {
my_error(ER_QUERY_ON_MASTER, MYF(0), mysql_error(mysql)); my_sprintf(error_buffer, (error_buffer, ": %d : %s",
DBUG_RETURN(ER_QUERY_ON_MASTER); mysql_errno(mysql), mysql_error(mysql)));
retval= ER_QUERY_ON_FOREIGN_DATA_SRC;
goto error;
} }
result= mysql_store_result(mysql); result= mysql_store_result(mysql);
if (!result) if (!result)
{ {
table->status= STATUS_NOT_FOUND; retval= HA_ERR_END_OF_FILE;
DBUG_RETURN(HA_ERR_END_OF_FILE); goto error;
} }
/*
This basically says that the record in table->record[0] is legal,
and that it is ok to use this record, for whatever reason, such
as with a join (without it, joins will not work)
*/
table->status=0;
retval= rnd_next(buf);
DBUG_RETURN(retval);
if (mysql_errno(mysql)) error:
if (result)
{ {
table->status= STATUS_NOT_FOUND; mysql_free_result(result);
DBUG_RETURN(mysql_errno(mysql)); result= 0;
} }
/* table->status= STATUS_NOT_FOUND;
This basically says that the record in table->record[0] is legal, and that it is my_error(retval, MYF(0), error_buffer);
ok to use this record, for whatever reason, such as with a join (without it, joins DBUG_RETURN(retval);
will not work)
*/
table->status=0;
DBUG_RETURN(rnd_next(buf));
} }
/* Initialized at each key walk (called multiple times unlike rnd_init()) */ /* Initialized at each key walk (called multiple times unlike rnd_init()) */
int ha_federated::index_init(uint keynr) int ha_federated::index_init(uint keynr)
{ {
int error;
DBUG_ENTER("ha_federated::index_init"); DBUG_ENTER("ha_federated::index_init");
DBUG_PRINT("info", DBUG_PRINT("info",
("table: '%s' key: %d", table->s->table_name, keynr)); ("table: '%s' key: %d", table->s->table_name, keynr));
...@@ -1550,14 +2074,90 @@ int ha_federated::index_init(uint keynr) ...@@ -1550,14 +2074,90 @@ int ha_federated::index_init(uint keynr)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/*
int read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range, bool sorted);
*/
int ha_federated::read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range, bool sorted)
{
char sql_query_buffer[FEDERATED_QUERY_BUFFER_SIZE];
int retval;
String sql_query(sql_query_buffer,
sizeof(sql_query_buffer),
&my_charset_bin);
DBUG_ENTER("ha_federated::read_range_first");
if (start_key == NULL && end_key == NULL)
DBUG_RETURN(0);
sql_query.length(0);
sql_query.append(share->select_query);
create_where_from_key(&sql_query,
&table->key_info[active_index],
start_key, end_key, NULL);
if (mysql_real_query(mysql, sql_query.ptr(), sql_query.length()))
{
retval= ER_QUERY_ON_FOREIGN_DATA_SRC;
goto error;
}
sql_query.length(0);
if (result)
{
DBUG_PRINT("info",
("mysql_free_result address %lx", result));
mysql_free_result(result);
result= 0;
}
result= mysql_store_result(mysql);
if (!result)
{
retval= HA_ERR_END_OF_FILE;
goto error;
}
/* This was successful, please let it be known! */
table->status=0;
retval= rnd_next(table->record[0]);
DBUG_RETURN(retval);
error:
table->status= STATUS_NOT_FOUND;
if (result)
{
DBUG_PRINT("info", ("mysql_free_result address %lx", result));
mysql_free_result(result);
result= 0;
}
DBUG_RETURN(retval);
}
int ha_federated::read_range_next()
{
int retval;
DBUG_ENTER("ha_federated::read_range_next");
retval= rnd_next(table->record[0]);
DBUG_RETURN(retval);
}
/* Used to read forward through the index. */ /* Used to read forward through the index. */
int ha_federated::index_next(byte *buf) int ha_federated::index_next(byte *buf)
{ {
int retval;
DBUG_ENTER("ha_federated::index_next"); DBUG_ENTER("ha_federated::index_next");
DBUG_RETURN(rnd_next(buf)); statistic_increment(table->in_use->status_var.ha_read_next_count,
&LOCK_status);
retval= rnd_next(buf);
DBUG_RETURN(retval);
} }
/* /*
rnd_init() is called when the system wants the storage engine to do a table rnd_init() is called when the system wants the storage engine to do a table
scan. scan.
...@@ -1573,12 +2173,15 @@ int ha_federated::index_next(byte *buf) ...@@ -1573,12 +2173,15 @@ int ha_federated::index_next(byte *buf)
int ha_federated::rnd_init(bool scan) int ha_federated::rnd_init(bool scan)
{ {
DBUG_ENTER("ha_federated::rnd_init"); int num_fields, rows;
int retval;
char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
DBUG_ENTER("ha_federated::rnd_init");
/* /*
This 'scan' flag is incredibly important for this handler to work The use of the 'scan' flag is incredibly important for this handler
properly, especially with updates containing WHERE clauses using to work properly, especially with updates containing WHERE clauses
indexed columns. using indexed columns.
When the initial query contains a WHERE clause of the query using an When the initial query contains a WHERE clause of the query using an
indexed column, it's index_read_idx that selects the exact record from indexed column, it's index_read_idx that selects the exact record from
...@@ -1621,32 +2224,40 @@ int ha_federated::rnd_init(bool scan) ...@@ -1621,32 +2224,40 @@ int ha_federated::rnd_init(bool scan)
result= 0; result= 0;
} }
if (mysql_real_query if (mysql_real_query(mysql,
(mysql, share->select_query, strlen(share->select_query))) share->select_query,
{ strlen(share->select_query)))
my_error(ER_QUERY_ON_MASTER, MYF(0), mysql_error(mysql)); goto error;
DBUG_RETURN(ER_QUERY_ON_MASTER);
}
result= mysql_store_result(mysql);
if (mysql_errno(mysql)) result= mysql_store_result(mysql);
DBUG_RETURN(mysql_errno(mysql)); if (!result)
goto error;
} }
DBUG_RETURN(0); DBUG_RETURN(0);
error:
retval= ER_QUERY_ON_FOREIGN_DATA_SRC;
my_sprintf(error_buffer, (error_buffer, ": %d : %s",
mysql_errno(mysql), mysql_error(mysql)));
my_error(retval, MYF(0), error_buffer);
DBUG_PRINT("info",
("return error code %d", retval));
DBUG_RETURN(retval);
} }
int ha_federated::rnd_end() int ha_federated::rnd_end()
{ {
int retval;
DBUG_ENTER("ha_federated::rnd_end"); DBUG_ENTER("ha_federated::rnd_end");
if (result) if (result)
{ {
DBUG_PRINT("info", ("mysql_free_result address %lx", result)); DBUG_PRINT("info", ("mysql_free_result address %lx", result));
mysql_free_result(result); mysql_free_result(result);
result= 0; result= 0;
} }
retval= index_end();
mysql_free_result(result); DBUG_RETURN(retval);
DBUG_RETURN(index_end());
} }
int ha_federated::index_end(void) int ha_federated::index_end(void)
...@@ -1668,6 +2279,7 @@ int ha_federated::index_end(void) ...@@ -1668,6 +2279,7 @@ int ha_federated::index_end(void)
int ha_federated::rnd_next(byte *buf) int ha_federated::rnd_next(byte *buf)
{ {
int retval;
MYSQL_ROW row; MYSQL_ROW row;
DBUG_ENTER("ha_federated::rnd_next"); DBUG_ENTER("ha_federated::rnd_next");
...@@ -1687,7 +2299,8 @@ int ha_federated::rnd_next(byte *buf) ...@@ -1687,7 +2299,8 @@ int ha_federated::rnd_next(byte *buf)
if (!(row= mysql_fetch_row(result))) if (!(row= mysql_fetch_row(result)))
DBUG_RETURN(HA_ERR_END_OF_FILE); DBUG_RETURN(HA_ERR_END_OF_FILE);
DBUG_RETURN(convert_row_to_internal_format(buf, row)); retval= convert_row_to_internal_format(buf, row);
DBUG_RETURN(retval);
} }
...@@ -1734,13 +2347,15 @@ int ha_federated::rnd_pos(byte *buf, byte *pos) ...@@ -1734,13 +2347,15 @@ int ha_federated::rnd_pos(byte *buf, byte *pos)
*/ */
if (scan_flag) if (scan_flag)
{ {
int retval;
statistic_increment(table->in_use->status_var.ha_read_rnd_count, statistic_increment(table->in_use->status_var.ha_read_rnd_count,
&LOCK_status); &LOCK_status);
memcpy_fixed(&current_position, pos, sizeof(MYSQL_ROW_OFFSET)); // pos memcpy_fixed(&current_position, pos, sizeof(MYSQL_ROW_OFFSET)); // pos
/* is not aligned */ /* is not aligned */
result->current_row= 0; result->current_row= 0;
result->data_cursor= current_position; result->data_cursor= current_position;
DBUG_RETURN(rnd_next(buf)); retval= rnd_next(buf);
DBUG_RETURN(retval);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -1789,12 +2404,97 @@ int ha_federated::rnd_pos(byte *buf, byte *pos) ...@@ -1789,12 +2404,97 @@ int ha_federated::rnd_pos(byte *buf, byte *pos)
sql_update.cc sql_update.cc
*/ */
/* FIX: later version provide better information to the optimizer */
void ha_federated::info(uint flag) void ha_federated::info(uint flag)
{ {
char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char status_buf[FEDERATED_QUERY_BUFFER_SIZE];
char escaped_table_name[FEDERATED_QUERY_BUFFER_SIZE];
int error;
uint error_code;
MYSQL_RES *result=0;
MYSQL_ROW row;
String status_query_string(status_buf, sizeof(status_buf), &my_charset_bin);
DBUG_ENTER("ha_federated::info"); DBUG_ENTER("ha_federated::info");
records= 10000; // fix later
error_code= ER_QUERY_ON_FOREIGN_DATA_SRC;
/* we want not to show table status if not needed to do so */
if (flag & (HA_STATUS_VARIABLE | HA_STATUS_CONST))
{
status_query_string.length(0);
status_query_string.append("SHOW TABLE STATUS LIKE '", 24);
escape_string_for_mysql(&my_charset_bin, (char *)escaped_table_name,
sizeof(escaped_table_name),
share->table_name,
share->table_name_length);
status_query_string.append(escaped_table_name);
status_query_string.append("'");
if (mysql_real_query(mysql, status_query_string.ptr(),
status_query_string.length()))
goto error;
status_query_string.length(0);
result= mysql_store_result(mysql);
if (! result)
goto error;
if (! mysql_num_rows(result))
goto error;
if (!(row= mysql_fetch_row(result)))
goto error;
if (flag & HA_STATUS_VARIABLE | HA_STATUS_CONST)
{
/*
deleted is set in ha_federated::info
*/
/*
need to figure out what this means as far as federated is concerned,
since we don't have a "file"
data_file_length = ?
index_file_length = ?
delete_length = ?
*/
if (row[4] != NULL)
records= (ha_rows) my_strtoll10(row[4], (char**) 0, &error);
if (row[5] != NULL)
mean_rec_length= (ha_rows) my_strtoll10(row[5], (char**) 0, &error);
if (row[12] != NULL)
update_time= (ha_rows) my_strtoll10(row[12], (char**) 0, &error);
if (row[13] != NULL)
check_time= (ha_rows) my_strtoll10(row[13], (char**) 0, &error);
}
if (flag & HA_STATUS_CONST)
{
TABLE_SHARE *share= table->s;
block_size= 4096;
}
}
if (result)
{
mysql_free_result(result);
result= 0;
}
DBUG_VOID_RETURN;
error:
if (result)
{
mysql_free_result(result);
result= 0;
}
my_sprintf(error_buffer,
(error_buffer,
": %d : %s",
mysql_errno(mysql), mysql_error(mysql)));
my_error(error_code, MYF(0), error_buffer);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -1815,22 +2515,31 @@ int ha_federated::delete_all_rows() ...@@ -1815,22 +2515,31 @@ int ha_federated::delete_all_rows()
{ {
DBUG_ENTER("ha_federated::delete_all_rows"); DBUG_ENTER("ha_federated::delete_all_rows");
char query_buffer[IO_SIZE]; char query_buffer[FEDERATED_QUERY_BUFFER_SIZE];
String query(query_buffer, sizeof(query_buffer), &my_charset_bin); String query(query_buffer, sizeof(query_buffer), &my_charset_bin);
query.length(0); query.length(0);
query.set_charset(system_charset_info); query.set_charset(system_charset_info);
query.append("TRUNCATE `"); query.append("TRUNCATE `", 10);
query.append(share->table_base_name); query.append(share->table_name);
query.append("`"); query.append("`", 1);
/*
TRUNCATE won't return anything in mysql_affected_rows
*/
deleted+= records;
if (mysql_real_query(mysql, query.ptr(), query.length())) if (mysql_real_query(mysql, query.ptr(), query.length()))
{ {
my_error(ER_QUERY_ON_MASTER, MYF(0), mysql_error(mysql)); int error_code= ER_QUERY_ON_FOREIGN_DATA_SRC;
DBUG_RETURN(ER_QUERY_ON_MASTER); char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
my_sprintf(error_buffer,
(error_buffer,
": %d : %s",
mysql_errno(mysql), mysql_error(mysql)));
my_error(error_code, MYF(0), error_buffer);
DBUG_RETURN(error_code);
} }
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
} }
...@@ -1878,7 +2587,7 @@ THR_LOCK_DATA **ha_federated::store_lock(THD *thd, ...@@ -1878,7 +2587,7 @@ THR_LOCK_DATA **ha_federated::store_lock(THD *thd,
*/ */
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
lock_type <= TL_WRITE) && !thd->in_lock_tables && !thd->tablespace_op) lock_type <= TL_WRITE) && !thd->in_lock_tables)
lock_type= TL_WRITE_ALLOW_WRITE; lock_type= TL_WRITE_ALLOW_WRITE;
/* /*
...@@ -1908,28 +2617,41 @@ THR_LOCK_DATA **ha_federated::store_lock(THD *thd, ...@@ -1908,28 +2617,41 @@ THR_LOCK_DATA **ha_federated::store_lock(THD *thd,
int ha_federated::create(const char *name, TABLE *table_arg, int ha_federated::create(const char *name, TABLE *table_arg,
HA_CREATE_INFO *create_info) HA_CREATE_INFO *create_info)
{ {
int connection_error=0; int retval= 0;
FEDERATED_SHARE tmp; /*
only a temporary share, to test the url
*/
FEDERATED_SHARE tmp_share;
DBUG_ENTER("ha_federated::create"); DBUG_ENTER("ha_federated::create");
if (parse_url(&tmp, table_arg, 1)) if ((retval= parse_url(&tmp_share, table_arg, 1)))
{
my_error(ER_CANT_CREATE_TABLE, MYF(0), name, 1);
goto error; goto error;
}
if ((connection_error= check_foreign_data_source(&tmp))) if ((retval= check_foreign_data_source(&tmp_share, 1)))
{
my_error(connection_error, MYF(0), name, 1);
goto error; goto error;
if (tmp_share.scheme)
{
DBUG_PRINT("info",
("ha_federated::create. Freeing tmp_share.scheme %lx",
tmp_share.scheme));
my_free((gptr) tmp_share.scheme, MYF(0));
tmp_share.scheme= 0;
} }
DBUG_PRINT("info", ("no errors, returning %d", retval));
my_free((gptr) tmp.scheme, MYF(0)); DBUG_RETURN(retval);
DBUG_RETURN(0);
error: error:
DBUG_PRINT("info", ("errors, returning %d", ER_CANT_CREATE_TABLE)); if (tmp_share.scheme)
my_free((gptr) tmp.scheme, MYF(0)); {
DBUG_RETURN(ER_CANT_CREATE_TABLE); DBUG_PRINT("info",
("error in ha_federated::create. Freeing tmp_share.scheme %lx",
tmp_share.scheme));
my_free((gptr) tmp_share.scheme, MYF(0));
tmp_share.scheme= 0;
}
DBUG_PRINT("info", ("errors, returning %d", retval));
DBUG_RETURN(retval);
} }
#endif /* HAVE_FEDERATED_DB */ #endif /* HAVE_FEDERATED_DB */
...@@ -26,16 +26,16 @@ ...@@ -26,16 +26,16 @@
#endif #endif
#include <mysql.h> #include <mysql.h>
//#include <client.h>
#define FEDERATED_QUERY_BUFFER_SIZE STRING_BUFFER_USUAL_SIZE * 5
#define FEDERATED_RECORDS_IN_RANGE 2
/* /*
FEDERATED_SHARE is a structure that will be shared amoung all open handlers FEDERATED_SHARE is a structure that will be shared amoung all open handlers
The example implements the minimum of what you will probably need. The example implements the minimum of what you will probably need.
*/ */
typedef struct st_federated_share { typedef struct st_federated_share {
char *table_name; /*
char *table_base_name;
/*
the primary select query to be used in rnd_init the primary select query to be used in rnd_init
*/ */
char *select_query; char *select_query;
...@@ -47,11 +47,12 @@ typedef struct st_federated_share { ...@@ -47,11 +47,12 @@ typedef struct st_federated_share {
char *username; char *username;
char *password; char *password;
char *database; char *database;
char *table_name;
char *table; char *table;
char *socket; char *socket;
char *sport; char *sport;
int port; ushort port;
uint table_name_length,table_base_name_length,use_count; uint table_name_length,use_count;
pthread_mutex_t mutex; pthread_mutex_t mutex;
THR_LOCK lock; THR_LOCK lock;
} FEDERATED_SHARE; } FEDERATED_SHARE;
...@@ -63,7 +64,7 @@ class ha_federated: public handler ...@@ -63,7 +64,7 @@ class ha_federated: public handler
{ {
THR_LOCK_DATA lock; /* MySQL lock */ THR_LOCK_DATA lock; /* MySQL lock */
FEDERATED_SHARE *share; /* Shared lock info */ FEDERATED_SHARE *share; /* Shared lock info */
MYSQL *mysql; MYSQL *mysql; /* MySQL connection */
MYSQL_RES *result; MYSQL_RES *result;
bool scan_flag; bool scan_flag;
uint ref_length; uint ref_length;
...@@ -77,11 +78,13 @@ private: ...@@ -77,11 +78,13 @@ private:
*/ */
uint convert_row_to_internal_format(byte *buf, MYSQL_ROW row); uint convert_row_to_internal_format(byte *buf, MYSQL_ROW row);
bool create_where_from_key(String *to, KEY *key_info, bool create_where_from_key(String *to, KEY *key_info,
const byte *key, uint key_length); const key_range *start_key,
const key_range *end_key,
bool records_in_range);
public: public:
ha_federated(TABLE *table): handler(table), ha_federated(TABLE *table): handler(table),
mysql(0), result(0), scan_flag(0), mysql(0), result(0), scan_flag(0),
ref_length(sizeof(MYSQL_ROW_OFFSET)), current_position(0) ref_length(sizeof(MYSQL_ROW_OFFSET)), current_position(0)
{ {
} }
...@@ -94,20 +97,20 @@ public: ...@@ -94,20 +97,20 @@ public:
The name of the index type that will be used for display The name of the index type that will be used for display
don't implement this method unless you really have indexes don't implement this method unless you really have indexes
*/ */
// perhaps get index type
const char *index_type(uint inx) { return "REMOTE"; } const char *index_type(uint inx) { return "REMOTE"; }
const char **bas_ext() const; const char **bas_ext() const;
/* /*
This is a list of flags that says what the storage engine This is a list of flags that says what the storage engine
implements. The current table flags are documented in implements. The current table flags are documented in
handler.h handler.h
Serg: Double check these (Brian)
// FIX add blob support
*/ */
ulong table_flags() const ulong table_flags() const
{ {
return (HA_TABLE_SCAN_ON_INDEX | HA_NOT_EXACT_COUNT | /* fix server to be able to get remote server table flags */
HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED | return (HA_NOT_EXACT_COUNT |
HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS); HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED | HA_REC_NOT_IN_SEQ |
HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS| HA_NO_PREFIX_CHAR_KEYS);
} }
/* /*
This is a bitmap of flags that says how the storage engine This is a bitmap of flags that says how the storage engine
...@@ -119,29 +122,40 @@ public: ...@@ -119,29 +122,40 @@ public:
If all_parts it's set, MySQL want to know the flags for the combined If all_parts it's set, MySQL want to know the flags for the combined
index up to and including 'part'. index up to and including 'part'.
*/ */
/* fix server to be able to get remote server index flags */
ulong index_flags(uint inx, uint part, bool all_parts) const ulong index_flags(uint inx, uint part, bool all_parts) const
{ {
return (HA_READ_NEXT); return (HA_READ_NEXT | HA_READ_RANGE | HA_READ_AFTER_KEY);
// return (HA_READ_NEXT | HA_ONLY_WHOLE_INDEX);
} }
uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; } uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_supported_keys() const { return MAX_KEY; } uint max_supported_keys() const { return MAX_KEY; }
uint max_supported_key_parts() const { return 1024; } uint max_supported_key_parts() const { return MAX_REF_PARTS; }
uint max_supported_key_length() const { return 1024; } uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
/* /*
Called in test_quick_select to determine if indexes should be used. Called in test_quick_select to determine if indexes should be used.
Normally, we need to know number of blocks . For federated we need to
know number of blocks on remote side, and number of packets and blocks
on the network side (?)
Talk to Kostja about this - how to get the
number of rows * ...
disk scan time on other side (block size, size of the row) + network time ...
The reason for "records * 1000" is that such a large number forces
this to use indexes "
*/ */
virtual double scan_time() double scan_time()
{ {
DBUG_PRINT("ha_federated::scan_time", DBUG_PRINT("info",
("rows %d", records)); return (double)(records*2); ("records %d", records)); return (double)(records*1000);
} }
/* /*
The next method will never be called if you do not implement indexes. The next method will never be called if you do not implement indexes.
*/ */
virtual double read_time(uint index, uint ranges, ha_rows rows) double read_time(uint index, uint ranges, ha_rows rows)
{ return (double) rows / 20.0+1; } {
return (double) rows / 20.0+1;
}
const key_map *keys_to_use_for_scanning() { return &key_map_full; }
/* /*
Everything below are methods that we implment in ha_federated.cc. Everything below are methods that we implment in ha_federated.cc.
...@@ -151,16 +165,20 @@ public: ...@@ -151,16 +165,20 @@ public:
int open(const char *name, int mode, uint test_if_locked); // required int open(const char *name, int mode, uint test_if_locked); // required
int close(void); // required int close(void); // required
int write_row(byte * buf); int write_row(byte *buf);
int update_row(const byte * old_data, byte * new_data); int update_row(const byte *old_data, byte *new_data);
int delete_row(const byte * buf); int delete_row(const byte *buf);
int index_init(uint keynr); int index_init(uint keynr);
int index_read(byte * buf, const byte * key, int index_read(byte *buf, const byte *key,
uint key_len, enum ha_rkey_function find_flag); uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key, int index_read_idx(byte *buf, uint idx, const byte *key,
uint key_len, enum ha_rkey_function find_flag); uint key_len, enum ha_rkey_function find_flag);
int index_next(byte * buf); int index_next(byte *buf);
int index_end(); int index_end();
int read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range, bool sorted);
int read_range_next();
/* /*
unlike index_init(), rnd_init() can be called two times unlike index_init(), rnd_init() can be called two times
without rnd_end() in between (it only makes sense if scan=1). without rnd_end() in between (it only makes sense if scan=1).
...@@ -172,13 +190,15 @@ public: ...@@ -172,13 +190,15 @@ public:
int rnd_init(bool scan); //required int rnd_init(bool scan); //required
int rnd_end(); int rnd_end();
int rnd_next(byte *buf); //required int rnd_next(byte *buf); //required
int rnd_pos(byte * buf, byte *pos); //required int rnd_pos(byte *buf, byte *pos); //required
void position(const byte *record); //required void position(const byte *record); //required
void info(uint); //required void info(uint); //required
int delete_all_rows(void); int delete_all_rows(void);
int create(const char *name, TABLE *form, int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); //required HA_CREATE_INFO *create_info); //required
ha_rows records_in_range(uint inx, key_range *start_key,
key_range *end_key);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); //required enum thr_lock_type lock_type); //required
......
...@@ -5370,3 +5370,15 @@ ER_SCALE_BIGGER_THAN_PRECISION 42000 S1009 ...@@ -5370,3 +5370,15 @@ ER_SCALE_BIGGER_THAN_PRECISION 42000 S1009
eng "Scale may not be larger than the precision (column '%-.64s')." eng "Scale may not be larger than the precision (column '%-.64s')."
ER_WRONG_LOCK_OF_SYSTEM_TABLE ER_WRONG_LOCK_OF_SYSTEM_TABLE
eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables" eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables"
ER_CONNECT_TO_FOREIGN_DATA_SRC
eng "Unable to connect to foreign data source - database '%s'!"
ER_QUERY_ON_FOREIGN_DATA_SRC
eng "There was a problem processing the query on the foreign data source. Data source error: '%-.64s'"
ER_FOREIGN_DATA_SRC_DOESNT_EXIST
eng "The foreign data source you are trying to reference does not exist. Data source error : '%-.64s'"
ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE
eng "Can't create federated table. The data source connection string '%-.64s' is not in the correct format"
ER_FOREIGN_DATA_STRING_INVALID
eng "The data source connection string '%-.64s' is not in the correct format"
ER_CANT_CREATE_FEDERATED_TABLE
eng "Can't create federated table. Foreign data src error : '%-.64s'"
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