Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
8ad2472e
Commit
8ad2472e
authored
Mar 30, 2007
by
istruewing@chilla.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-5.1
into chilla.local:/home/mydev/mysql-5.1-axmrg
parents
12960809
facba6ba
Changes
22
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
1392 additions
and
369 deletions
+1392
-369
mysql-test/r/federated_server.result
mysql-test/r/federated_server.result
+185
-10
mysql-test/r/heap_btree.result
mysql-test/r/heap_btree.result
+27
-0
mysql-test/r/myisam.result
mysql-test/r/myisam.result
+150
-0
mysql-test/t/federated_server.test
mysql-test/t/federated_server.test
+217
-5
mysql-test/t/heap_btree.test
mysql-test/t/heap_btree.test
+32
-0
mysql-test/t/myisam.test
mysql-test/t/myisam.test
+144
-0
mysys/my_pread.c
mysys/my_pread.c
+4
-4
mysys/my_pthread.c
mysys/my_pthread.c
+0
-2
mysys/my_redel.c
mysys/my_redel.c
+1
-1
sql/mysql_priv.h
sql/mysql_priv.h
+3
-0
sql/sql_base.cc
sql/sql_base.cc
+66
-0
sql/sql_parse.cc
sql/sql_parse.cc
+13
-1
sql/sql_servers.cc
sql/sql_servers.cc
+246
-201
sql/sql_servers.h
sql/sql_servers.h
+6
-27
storage/federated/ha_federated.cc
storage/federated/ha_federated.cc
+155
-101
storage/federated/ha_federated.h
storage/federated/ha_federated.h
+3
-0
storage/heap/ha_heap.cc
storage/heap/ha_heap.cc
+4
-1
storage/heap/hp_write.c
storage/heap/hp_write.c
+0
-1
storage/myisam/ha_myisam.cc
storage/myisam/ha_myisam.cc
+51
-1
storage/myisam/mi_create.c
storage/myisam/mi_create.c
+15
-6
storage/myisam/mi_range.c
storage/myisam/mi_range.c
+35
-1
storage/myisam/mi_search.c
storage/myisam/mi_search.c
+35
-7
No files found.
mysql-test/r/federated_server.result
View file @
8ad2472e
...
@@ -20,6 +20,14 @@ CREATE TABLE first_db.t1 (
...
@@ -20,6 +20,14 @@ CREATE TABLE first_db.t1 (
`name` varchar(64) NOT NULL default ''
`name` varchar(64) NOT NULL default ''
)
)
DEFAULT CHARSET=latin1;
DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS first_db.t2;
Warnings:
Note 1051 Unknown table 't2'
CREATE TABLE first_db.t2 (
`id` int(20) NOT NULL,
`name` varchar(64) NOT NULL default ''
)
DEFAULT CHARSET=latin1;
use second_db;
use second_db;
DROP TABLE IF EXISTS second_db.t1;
DROP TABLE IF EXISTS second_db.t1;
Warnings:
Warnings:
...
@@ -29,6 +37,14 @@ CREATE TABLE second_db.t1 (
...
@@ -29,6 +37,14 @@ CREATE TABLE second_db.t1 (
`name` varchar(64) NOT NULL default ''
`name` varchar(64) NOT NULL default ''
)
)
DEFAULT CHARSET=latin1;
DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS second_db.t2;
Warnings:
Note 1051 Unknown table 't2'
CREATE TABLE second_db.t2 (
`id` int(20) NOT NULL,
`name` varchar(64) NOT NULL default ''
)
DEFAULT CHARSET=latin1;
drop server if exists 'server_one';
drop server if exists 'server_one';
create server 'server_one' foreign data wrapper 'mysql' options
create server 'server_one' foreign data wrapper 'mysql' options
(HOST '127.0.0.1',
(HOST '127.0.0.1',
...
@@ -60,10 +76,10 @@ CREATE TABLE federated.old (
...
@@ -60,10 +76,10 @@ CREATE TABLE federated.old (
)
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/first_db/t1';
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/first_db/t1';
INSERT INTO federated.old (id, name) values (1, 'federated.old
url
');
INSERT INTO federated.old (id, name) values (1, 'federated.old
-> first_db.t1, url format
');
SELECT * FROM federated.old;
SELECT * FROM federated.old;
id name
id name
1 federated.old
url
1 federated.old
-> first_db.t1, url format
DROP TABLE IF EXISTS federated.old2;
DROP TABLE IF EXISTS federated.old2;
Warnings:
Warnings:
Note 1051 Unknown table 'old2'
Note 1051 Unknown table 'old2'
...
@@ -72,8 +88,37 @@ CREATE TABLE federated.old2 (
...
@@ -72,8 +88,37 @@ CREATE TABLE federated.old2 (
`name` varchar(64) NOT NULL default ''
`name` varchar(64) NOT NULL default ''
)
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/first_db/t2';
INSERT INTO federated.old2 (id, name) values (1, 'federated.old2-> first_db.t2, url format');
SELECT * FROM federated.old2;
id name
1 federated.old2-> first_db.t2, url format
DROP TABLE IF EXISTS federated.urldb2t1;
Warnings:
Note 1051 Unknown table 'urldb2t1'
CREATE TABLE federated.urldb2t1 (
`id` int(20) NOT NULL,
`name` varchar(64) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/second_db/t1';
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/second_db/t1';
INSERT INTO federated.old2 (id, name) values (1, 'federated.old2 url');
INSERT INTO federated.urldb2t1 (id, name) values (1, 'federated.urldb2t1 -> second_db.t1, url format');
SELECT * FROM federated.urldb2t1;
id name
1 federated.urldb2t1 -> second_db.t1, url format
DROP TABLE IF EXISTS federated.urldb2t2;
Warnings:
Note 1051 Unknown table 'urldb2t2'
CREATE TABLE federated.urldb2t2 (
`id` int(20) NOT NULL,
`name` varchar(64) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/second_db/t2';
INSERT INTO federated.urldb2t2 (id, name) values (1, 'federated.urldb2t2 -> second_db.t2, url format');
SELECT * FROM federated.urldb2t2;
id name
1 federated.urldb2t2 -> second_db.t2, url format
DROP TABLE IF EXISTS federated.t1;
DROP TABLE IF EXISTS federated.t1;
Warnings:
Warnings:
Note 1051 Unknown table 't1'
Note 1051 Unknown table 't1'
...
@@ -83,18 +128,38 @@ CREATE TABLE federated.t1 (
...
@@ -83,18 +128,38 @@ CREATE TABLE federated.t1 (
)
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='server_one';
CONNECTION='server_one';
INSERT INTO federated.t1 (id, name) values (1, 'server_one, new scheme');
INSERT INTO federated.t1 (id, name) values (1, 'server_one, new scheme
, first_db.t1
');
SELECT * FROM federated.t1;
SELECT * FROM federated.t1;
id name
id name
1 federated.old url
1 federated.old-> first_db.t1, url format
1 server_one, new scheme
1 server_one, new scheme, first_db.t1
DROP TABLE IF EXISTS federated.whatever;
Warnings:
Note 1051 Unknown table 'whatever'
CREATE TABLE federated.whatever (
`id` int(20) NOT NULL,
`name` varchar(64) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='server_one/t1';
INSERT INTO federated.whatever (id, name) values (1, 'server_one, new scheme, whatever, first_db.t1');
SELECT * FROM federated.whatever;
id name
1 federated.old-> first_db.t1, url format
1 server_one, new scheme, first_db.t1
1 server_one, new scheme, whatever, first_db.t1
ALTER SERVER 'server_one' options(DATABASE 'second_db');
ALTER SERVER 'server_one' options(DATABASE 'second_db');
flush tables;
INSERT INTO federated.t1 (id, name) values (1, 'server_two, new scheme, second_db.t1');
INSERT INTO federated.t1 (id, name) values (1, 'server_two, new scheme');
SELECT * FROM federated.t1;
SELECT * FROM federated.t1;
id name
id name
1 federated.old2 url
1 federated.urldb2t1 -> second_db.t1, url format
1 server_two, new scheme
1 server_two, new scheme, second_db.t1
INSERT INTO federated.whatever (id, name) values (1, 'server_two, new scheme, whatever, second_db.t1');
SELECT * FROM federated.whatever;
id name
1 federated.urldb2t1 -> second_db.t1, url format
1 server_two, new scheme, second_db.t1
1 server_two, new scheme, whatever, second_db.t1
drop table federated.t1;
drop table federated.t1;
drop server 'server_one';
drop server 'server_one';
drop server 'server_two';
drop server 'server_two';
...
@@ -104,6 +169,116 @@ drop table first_db.t1;
...
@@ -104,6 +169,116 @@ drop table first_db.t1;
drop table second_db.t1;
drop table second_db.t1;
drop database first_db;
drop database first_db;
drop database second_db;
drop database second_db;
create database db_legitimate;
create database db_bogus;
use db_legitimate;
CREATE TABLE db_legitimate.t1 (
`id` int(20) NOT NULL,
`name` varchar(64) NOT NULL default ''
);
INSERT INTO db_legitimate.t1 VALUES ('1','this is legitimate');
use db_bogus;
CREATE TABLE db_bogus.t1 (
`id` int(20) NOT NULL,
`name` varchar(64) NOT NULL default ''
)
;
INSERT INTO db_bogus.t1 VALUES ('2','this is bogus');
create server 's1' foreign data wrapper 'mysql' options
(HOST '127.0.0.1',
DATABASE 'db_legitimate',
USER 'root',
PASSWORD '',
PORT SLAVE_PORT,
SOCKET '',
OWNER 'root');
create user guest_select@localhost;
grant select on federated.* to guest_select@localhost;
create user guest_super@localhost;
grant select,SUPER,RELOAD on *.* to guest_super@localhost;
create user guest_usage@localhost;
grant usage on *.* to guest_usage@localhost;
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(64) NOT NULL default ''
) ENGINE = FEDERATED CONNECTION = 's1';
select * from federated.t1;
id name
1 this is legitimate
alter server s1 options (database 'db_bogus');
ERROR 42000: Access denied; you need the SUPER privilege for this operation
flush tables;
select * from federated.t1;
id name
1 this is legitimate
alter server s1 options (database 'db_bogus');
ERROR 42000: Access denied; you need the SUPER privilege for this operation
flush tables;
select * from federated.t1;
id name
1 this is legitimate
alter server s1 options (database 'db_bogus');
flush tables;
select * from federated.t1;
id name
2 this is bogus
drop server if exists 's1';
ERROR 42000: Access denied; you need the SUPER privilege for this operation
create server 's1' foreign data wrapper 'mysql' options
(HOST '127.0.0.1',
DATABASE 'db_legitimate',
USER 'root',
PASSWORD '',
PORT SLAVE_PORT,
SOCKET '',
OWNER 'root');
ERROR 42000: Access denied; you need the SUPER privilege for this operation
drop server 's1';
create server 's1' foreign data wrapper 'mysql' options
(HOST '127.0.0.1',
DATABASE 'db_legitimate',
USER 'root',
PASSWORD '',
PORT SLAVE_PORT,
SOCKET '',
OWNER 'root');
flush tables;
select * from federated.t1;
id name
1 this is legitimate
drop database db_legitimate;
drop database db_bogus;
drop user guest_super@localhost;
drop user guest_usage@localhost;
drop user guest_select@localhost;
drop table federated.t1;
drop server 's1';
# End of 5.1 tests
use test;
create procedure p1 ()
begin
DECLARE v INT DEFAULT 0;
DECLARE e INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET e = e + 1;
WHILE v < 10000 do
CREATE SERVER s
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');
ALTER SERVER s OPTIONS (USER 'Remote');
DROP SERVER s;
SET v = v + 1;
END WHILE;
SELECT e > 0;
END//
use test;
call p1();
call p1();
e > 0
1
e > 0
1
drop procedure p1;
drop server if exists s;
DROP TABLE IF EXISTS federated.t1;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1;
DROP TABLE IF EXISTS federated.t1;
...
...
mysql-test/r/heap_btree.result
View file @
8ad2472e
...
@@ -280,6 +280,33 @@ a
...
@@ -280,6 +280,33 @@ a
1
1
1
1
drop table t1;
drop table t1;
CREATE TABLE t1 (
c1 CHAR(3),
c2 INTEGER,
KEY USING BTREE(c1),
KEY USING BTREE(c2)
) ENGINE= MEMORY;
INSERT INTO t1 VALUES ('ABC',0), ('A',0), ('B',0), ('C',0);
UPDATE t1 SET c2= c2 + 1 WHERE c1 = 'A';
SELECT * FROM t1;
c1 c2
ABC 0
A 1
B 0
C 0
DROP TABLE t1;
CREATE TABLE t1 (
c1 ENUM('1', '2'),
UNIQUE USING BTREE(c1)
) ENGINE= MEMORY DEFAULT CHARSET= utf8;
INSERT INTO t1 VALUES('1'), ('2');
DROP TABLE t1;
CREATE TABLE t1 (
c1 SET('1', '2'),
UNIQUE USING BTREE(c1)
) ENGINE= MEMORY DEFAULT CHARSET= utf8;
INSERT INTO t1 VALUES('1'), ('2');
DROP TABLE t1;
End of 4.1 tests
End of 4.1 tests
CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory;
CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory;
INSERT INTO t1 VALUES(0);
INSERT INTO t1 VALUES(0);
...
...
mysql-test/r/myisam.result
View file @
8ad2472e
...
@@ -943,6 +943,156 @@ SHOW TABLE STATUS LIKE 't1';
...
@@ -943,6 +943,156 @@ SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 10 Dynamic X X X 72057594037927935 X X X X X X latin1_swedish_ci X max_rows=4100100100 avg_row_length=70100
t1 MyISAM 10 Dynamic X X X 72057594037927935 X X X X X X latin1_swedish_ci X max_rows=4100100100 avg_row_length=70100
DROP TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 (c1 TEXT NOT NULL, KEY c1 (c1(10))) ENGINE=MyISAM;
INSERT INTO t1 VALUES
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(CHAR(9,65)),
(CHAR(9,65)), (CHAR(9,65)), (CHAR(9,65)),
(''),
(''), (''), (''),
('
B'), (' B'), (' B'), (' B');
SELECT DISTINCT COUNT(*) FROM t1 WHERE c1 = '';
COUNT(*)
4
SELECT DISTINCT length(c1), c1 FROM t1 WHERE c1 = '';
length(c1) c1
0
SELECT DISTINCT COUNT(*) FROM t1 IGNORE INDEX (c1) WHERE c1 = '';
COUNT(*)
4
SELECT DISTINCT length(c1), c1 FROM t1 IGNORE INDEX (c1) WHERE c1 = '';
length(c1) c1
0
SELECT DISTINCT length(c1), c1 FROM t1 ORDER BY c1;
length(c1) c1
0
2 A
2 B
DROP TABLE t1;
End of 4.1 tests
End of 4.1 tests
set storage_engine=MyISAM;
set storage_engine=MyISAM;
drop table if exists t1,t2,t3;
drop table if exists t1,t2,t3;
...
...
mysql-test/t/federated_server.test
View file @
8ad2472e
...
@@ -17,6 +17,13 @@ CREATE TABLE first_db.t1 (
...
@@ -17,6 +17,13 @@ CREATE TABLE first_db.t1 (
)
)
DEFAULT
CHARSET
=
latin1
;
DEFAULT
CHARSET
=
latin1
;
DROP
TABLE
IF
EXISTS
first_db
.
t2
;
CREATE
TABLE
first_db
.
t2
(
`id`
int
(
20
)
NOT
NULL
,
`name`
varchar
(
64
)
NOT
NULL
default
''
)
DEFAULT
CHARSET
=
latin1
;
use
second_db
;
use
second_db
;
DROP
TABLE
IF
EXISTS
second_db
.
t1
;
DROP
TABLE
IF
EXISTS
second_db
.
t1
;
CREATE
TABLE
second_db
.
t1
(
CREATE
TABLE
second_db
.
t1
(
...
@@ -25,6 +32,13 @@ CREATE TABLE second_db.t1 (
...
@@ -25,6 +32,13 @@ CREATE TABLE second_db.t1 (
)
)
DEFAULT
CHARSET
=
latin1
;
DEFAULT
CHARSET
=
latin1
;
DROP
TABLE
IF
EXISTS
second_db
.
t2
;
CREATE
TABLE
second_db
.
t2
(
`id`
int
(
20
)
NOT
NULL
,
`name`
varchar
(
64
)
NOT
NULL
default
''
)
DEFAULT
CHARSET
=
latin1
;
connection
master
;
connection
master
;
drop
server
if
exists
'server_one'
;
drop
server
if
exists
'server_one'
;
...
@@ -61,7 +75,7 @@ eval CREATE TABLE federated.old (
...
@@ -61,7 +75,7 @@ eval CREATE TABLE federated.old (
ENGINE
=
"FEDERATED"
DEFAULT
CHARSET
=
latin1
ENGINE
=
"FEDERATED"
DEFAULT
CHARSET
=
latin1
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/first_db/t1'
;
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/first_db/t1'
;
INSERT
INTO
federated
.
old
(
id
,
name
)
values
(
1
,
'federated.old
url
'
);
INSERT
INTO
federated
.
old
(
id
,
name
)
values
(
1
,
'federated.old
-> first_db.t1, url format
'
);
SELECT
*
FROM
federated
.
old
;
SELECT
*
FROM
federated
.
old
;
...
@@ -72,9 +86,32 @@ eval CREATE TABLE federated.old2 (
...
@@ -72,9 +86,32 @@ eval CREATE TABLE federated.old2 (
`name`
varchar
(
64
)
NOT
NULL
default
''
`name`
varchar
(
64
)
NOT
NULL
default
''
)
)
ENGINE
=
"FEDERATED"
DEFAULT
CHARSET
=
latin1
ENGINE
=
"FEDERATED"
DEFAULT
CHARSET
=
latin1
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/first_db/t2'
;
INSERT
INTO
federated
.
old2
(
id
,
name
)
values
(
1
,
'federated.old2-> first_db.t2, url format'
);
SELECT
*
FROM
federated
.
old2
;
DROP
TABLE
IF
EXISTS
federated
.
urldb2t1
;
--
replace_result
$SLAVE_MYPORT
SLAVE_PORT
eval
CREATE
TABLE
federated
.
urldb2t1
(
`id`
int
(
20
)
NOT
NULL
,
`name`
varchar
(
64
)
NOT
NULL
default
''
)
ENGINE
=
"FEDERATED"
DEFAULT
CHARSET
=
latin1
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/second_db/t1'
;
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/second_db/t1'
;
INSERT
INTO
federated
.
urldb2t1
(
id
,
name
)
values
(
1
,
'federated.urldb2t1 -> second_db.t1, url format'
);
SELECT
*
FROM
federated
.
urldb2t1
;
INSERT
INTO
federated
.
old2
(
id
,
name
)
values
(
1
,
'federated.old2 url'
);
DROP
TABLE
IF
EXISTS
federated
.
urldb2t2
;
--
replace_result
$SLAVE_MYPORT
SLAVE_PORT
eval
CREATE
TABLE
federated
.
urldb2t2
(
`id`
int
(
20
)
NOT
NULL
,
`name`
varchar
(
64
)
NOT
NULL
default
''
)
ENGINE
=
"FEDERATED"
DEFAULT
CHARSET
=
latin1
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/second_db/t2'
;
INSERT
INTO
federated
.
urldb2t2
(
id
,
name
)
values
(
1
,
'federated.urldb2t2 -> second_db.t2, url format'
);
SELECT
*
FROM
federated
.
urldb2t2
;
DROP
TABLE
IF
EXISTS
federated
.
t1
;
DROP
TABLE
IF
EXISTS
federated
.
t1
;
CREATE
TABLE
federated
.
t1
(
CREATE
TABLE
federated
.
t1
(
...
@@ -84,17 +121,30 @@ CREATE TABLE federated.t1 (
...
@@ -84,17 +121,30 @@ CREATE TABLE federated.t1 (
ENGINE
=
"FEDERATED"
DEFAULT
CHARSET
=
latin1
ENGINE
=
"FEDERATED"
DEFAULT
CHARSET
=
latin1
CONNECTION
=
'server_one'
;
CONNECTION
=
'server_one'
;
INSERT
INTO
federated
.
t1
(
id
,
name
)
values
(
1
,
'server_one, new scheme'
);
INSERT
INTO
federated
.
t1
(
id
,
name
)
values
(
1
,
'server_one, new scheme
, first_db.t1
'
);
SELECT
*
FROM
federated
.
t1
;
SELECT
*
FROM
federated
.
t1
;
DROP
TABLE
IF
EXISTS
federated
.
whatever
;
CREATE
TABLE
federated
.
whatever
(
`id`
int
(
20
)
NOT
NULL
,
`name`
varchar
(
64
)
NOT
NULL
default
''
)
ENGINE
=
"FEDERATED"
DEFAULT
CHARSET
=
latin1
CONNECTION
=
'server_one/t1'
;
INSERT
INTO
federated
.
whatever
(
id
,
name
)
values
(
1
,
'server_one, new scheme, whatever, first_db.t1'
);
SELECT
*
FROM
federated
.
whatever
;
ALTER
SERVER
'server_one'
options
(
DATABASE
'second_db'
);
ALTER
SERVER
'server_one'
options
(
DATABASE
'second_db'
);
flush
tables
;
# FLUSH TABLES is now unneccessary
INSERT
INTO
federated
.
t1
(
id
,
name
)
values
(
1
,
'server_two, new scheme'
);
INSERT
INTO
federated
.
t1
(
id
,
name
)
values
(
1
,
'server_two, new scheme
, second_db.t1
'
);
SELECT
*
FROM
federated
.
t1
;
SELECT
*
FROM
federated
.
t1
;
INSERT
INTO
federated
.
whatever
(
id
,
name
)
values
(
1
,
'server_two, new scheme, whatever, second_db.t1'
);
SELECT
*
FROM
federated
.
whatever
;
drop
table
federated
.
t1
;
drop
table
federated
.
t1
;
drop
server
'server_one'
;
drop
server
'server_one'
;
...
@@ -107,4 +157,166 @@ drop table second_db.t1;
...
@@ -107,4 +157,166 @@ drop table second_db.t1;
drop
database
first_db
;
drop
database
first_db
;
drop
database
second_db
;
drop
database
second_db
;
#
# Bug#25671 - CREATE/DROP/ALTER SERVER should require privileges
#
# Changes to SERVER declarations should require SUPER privilege.
# Based upon test case by Giuseppe Maxia
create
database
db_legitimate
;
create
database
db_bogus
;
use
db_legitimate
;
CREATE
TABLE
db_legitimate
.
t1
(
`id`
int
(
20
)
NOT
NULL
,
`name`
varchar
(
64
)
NOT
NULL
default
''
);
INSERT
INTO
db_legitimate
.
t1
VALUES
(
'1'
,
'this is legitimate'
);
use
db_bogus
;
CREATE
TABLE
db_bogus
.
t1
(
`id`
int
(
20
)
NOT
NULL
,
`name`
varchar
(
64
)
NOT
NULL
default
''
)
;
INSERT
INTO
db_bogus
.
t1
VALUES
(
'2'
,
'this is bogus'
);
connection
master
;
--
replace_result
$SLAVE_MYPORT
SLAVE_PORT
eval
create
server
's1'
foreign
data
wrapper
'mysql'
options
(
HOST
'127.0.0.1'
,
DATABASE
'db_legitimate'
,
USER
'root'
,
PASSWORD
''
,
PORT
$SLAVE_MYPORT
,
SOCKET
''
,
OWNER
'root'
);
create
user
guest_select
@
localhost
;
grant
select
on
federated
.*
to
guest_select
@
localhost
;
create
user
guest_super
@
localhost
;
grant
select
,
SUPER
,
RELOAD
on
*.*
to
guest_super
@
localhost
;
create
user
guest_usage
@
localhost
;
grant
usage
on
*.*
to
guest_usage
@
localhost
;
CREATE
TABLE
federated
.
t1
(
`id`
int
(
20
)
NOT
NULL
,
`name`
varchar
(
64
)
NOT
NULL
default
''
)
ENGINE
=
FEDERATED
CONNECTION
=
's1'
;
select
*
from
federated
.
t1
;
connect
(
conn_select
,
127.0
.
0.1
,
guest_select
,,
federated
,
$MASTER_MYPORT
);
connect
(
conn_usage
,
127.0
.
0.1
,
guest_usage
,,,
$MASTER_MYPORT
);
connect
(
conn_super
,
127.0
.
0.1
,
guest_super
,,,
$MASTER_MYPORT
);
connection
conn_select
;
--
error
ER_SPECIFIC_ACCESS_DENIED_ERROR
alter
server
s1
options
(
database
'db_bogus'
);
connection
master
;
flush
tables
;
select
*
from
federated
.
t1
;
connection
conn_usage
;
--
error
ER_SPECIFIC_ACCESS_DENIED_ERROR
alter
server
s1
options
(
database
'db_bogus'
);
connection
master
;
flush
tables
;
select
*
from
federated
.
t1
;
connection
conn_super
;
alter
server
s1
options
(
database
'db_bogus'
);
connection
master
;
flush
tables
;
select
*
from
federated
.
t1
;
connection
conn_select
;
--
error
ER_SPECIFIC_ACCESS_DENIED_ERROR
drop
server
if
exists
's1'
;
--
replace_result
$SLAVE_MYPORT
SLAVE_PORT
--
error
ER_SPECIFIC_ACCESS_DENIED_ERROR
eval
create
server
's1'
foreign
data
wrapper
'mysql'
options
(
HOST
'127.0.0.1'
,
DATABASE
'db_legitimate'
,
USER
'root'
,
PASSWORD
''
,
PORT
$SLAVE_MYPORT
,
SOCKET
''
,
OWNER
'root'
);
connection
conn_super
;
drop
server
's1'
;
--
replace_result
$SLAVE_MYPORT
SLAVE_PORT
eval
create
server
's1'
foreign
data
wrapper
'mysql'
options
(
HOST
'127.0.0.1'
,
DATABASE
'db_legitimate'
,
USER
'root'
,
PASSWORD
''
,
PORT
$SLAVE_MYPORT
,
SOCKET
''
,
OWNER
'root'
);
connection
master
;
flush
tables
;
select
*
from
federated
.
t1
;
# clean up test
connection
slave
;
drop
database
db_legitimate
;
drop
database
db_bogus
;
disconnect
conn_select
;
disconnect
conn_usage
;
disconnect
conn_super
;
connection
master
;
drop
user
guest_super
@
localhost
;
drop
user
guest_usage
@
localhost
;
drop
user
guest_select
@
localhost
;
drop
table
federated
.
t1
;
drop
server
's1'
;
--
echo
# End of 5.1 tests
#
# Bug#25721 - deadlock with ALTER/CREATE SERVER
#
connect
(
other
,
localhost
,
root
,,);
connection
master
;
use
test
;
delimiter
//;
create
procedure
p1
()
begin
DECLARE
v
INT
DEFAULT
0
;
DECLARE
e
INT
DEFAULT
0
;
DECLARE
CONTINUE
HANDLER
FOR
SQLEXCEPTION
SET
e
=
e
+
1
;
WHILE
v
<
10000
do
CREATE
SERVER
s
FOREIGN
DATA
WRAPPER
mysql
OPTIONS
(
USER
'Remote'
,
HOST
'192.168.1.106'
,
DATABASE
'test'
);
ALTER
SERVER
s
OPTIONS
(
USER
'Remote'
);
DROP
SERVER
s
;
SET
v
=
v
+
1
;
END
WHILE
;
SELECT
e
>
0
;
END
//
delimiter
;
//
connection
other
;
use
test
;
send
call
p1
();
connection
master
;
call
p1
();
connection
other
;
reap
;
drop
procedure
p1
;
drop
server
if
exists
s
;
source
include
/
federated_cleanup
.
inc
;
source
include
/
federated_cleanup
.
inc
;
mysql-test/t/heap_btree.test
View file @
8ad2472e
...
@@ -182,6 +182,37 @@ delete from t1 where a >= 2;
...
@@ -182,6 +182,37 @@ delete from t1 where a >= 2;
select
a
from
t1
order
by
a
;
select
a
from
t1
order
by
a
;
drop
table
t1
;
drop
table
t1
;
#
# Bug#26996 - Update of a Field in a Memory Table ends with wrong result
#
CREATE
TABLE
t1
(
c1
CHAR
(
3
),
c2
INTEGER
,
KEY
USING
BTREE
(
c1
),
KEY
USING
BTREE
(
c2
)
)
ENGINE
=
MEMORY
;
INSERT
INTO
t1
VALUES
(
'ABC'
,
0
),
(
'A'
,
0
),
(
'B'
,
0
),
(
'C'
,
0
);
UPDATE
t1
SET
c2
=
c2
+
1
WHERE
c1
=
'A'
;
SELECT
*
FROM
t1
;
DROP
TABLE
t1
;
#
# Bug#24985 - UTF8 ENUM primary key on MEMORY using BTREE
# causes incorrect duplicate entries
#
CREATE
TABLE
t1
(
c1
ENUM
(
'1'
,
'2'
),
UNIQUE
USING
BTREE
(
c1
)
)
ENGINE
=
MEMORY
DEFAULT
CHARSET
=
utf8
;
INSERT
INTO
t1
VALUES
(
'1'
),
(
'2'
);
DROP
TABLE
t1
;
CREATE
TABLE
t1
(
c1
SET
(
'1'
,
'2'
),
UNIQUE
USING
BTREE
(
c1
)
)
ENGINE
=
MEMORY
DEFAULT
CHARSET
=
utf8
;
INSERT
INTO
t1
VALUES
(
'1'
),
(
'2'
);
DROP
TABLE
t1
;
--
echo
End
of
4.1
tests
--
echo
End
of
4.1
tests
#
#
...
@@ -205,3 +236,4 @@ INSERT INTO t1 VALUES(NULL),(NULL);
...
@@ -205,3 +236,4 @@ INSERT INTO t1 VALUES(NULL),(NULL);
DROP
TABLE
t1
;
DROP
TABLE
t1
;
--
echo
End
of
5.0
tests
--
echo
End
of
5.0
tests
mysql-test/t/myisam.test
View file @
8ad2472e
...
@@ -874,6 +874,150 @@ CREATE TABLE t1 (c1 TEXT) AVG_ROW_LENGTH=70100 MAX_ROWS=4100100100;
...
@@ -874,6 +874,150 @@ CREATE TABLE t1 (c1 TEXT) AVG_ROW_LENGTH=70100 MAX_ROWS=4100100100;
SHOW
TABLE
STATUS
LIKE
't1'
;
SHOW
TABLE
STATUS
LIKE
't1'
;
DROP
TABLE
t1
;
DROP
TABLE
t1
;
#
# Bug#26231 - select count(*) on myisam table returns wrong value
# when index is used
#
CREATE
TABLE
t1
(
c1
TEXT
NOT
NULL
,
KEY
c1
(
c1
(
10
)))
ENGINE
=
MyISAM
;
# Fill at least two key blocks. "Tab, A" must be in both blocks.
INSERT
INTO
t1
VALUES
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
CHAR
(
9
,
65
)),
(
''
),
(
''
),
(
''
),
(
''
),
(
' B'
),
(
' B'
),
(
' B'
),
(
' B'
);
SELECT
DISTINCT
COUNT
(
*
)
FROM
t1
WHERE
c1
=
''
;
SELECT
DISTINCT
length
(
c1
),
c1
FROM
t1
WHERE
c1
=
''
;
SELECT
DISTINCT
COUNT
(
*
)
FROM
t1
IGNORE
INDEX
(
c1
)
WHERE
c1
=
''
;
SELECT
DISTINCT
length
(
c1
),
c1
FROM
t1
IGNORE
INDEX
(
c1
)
WHERE
c1
=
''
;
SELECT
DISTINCT
length
(
c1
),
c1
FROM
t1
ORDER
BY
c1
;
DROP
TABLE
t1
;
--
echo
End
of
4.1
tests
--
echo
End
of
4.1
tests
...
...
mysys/my_pread.c
View file @
8ad2472e
...
@@ -37,7 +37,7 @@ uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
...
@@ -37,7 +37,7 @@ uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
errno
=
0
;
/* Linux doesn't reset this */
errno
=
0
;
/* Linux doesn't reset this */
#endif
#endif
#ifndef HAVE_PREAD
#ifndef HAVE_PREAD
off_t
old_offset
;
o
s_o
ff_t
old_offset
;
pthread_mutex_lock
(
&
my_file_info
[
Filedes
].
mutex
);
pthread_mutex_lock
(
&
my_file_info
[
Filedes
].
mutex
);
/*
/*
...
@@ -45,7 +45,7 @@ uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
...
@@ -45,7 +45,7 @@ uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
before seeking to the given offset
before seeking to the given offset
*/
*/
error
=
(
old_offset
=
(
off_t
)
lseek
(
Filedes
,
0L
,
MY_SEEK_CUR
))
==
-
1L
||
error
=
(
old_offset
=
lseek
(
Filedes
,
0L
,
MY_SEEK_CUR
))
==
-
1L
||
lseek
(
Filedes
,
offset
,
MY_SEEK_SET
)
==
-
1L
;
lseek
(
Filedes
,
offset
,
MY_SEEK_SET
)
==
-
1L
;
if
(
!
error
)
/* Seek was successful */
if
(
!
error
)
/* Seek was successful */
...
@@ -116,7 +116,7 @@ uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset,
...
@@ -116,7 +116,7 @@ uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset,
{
{
#ifndef HAVE_PREAD
#ifndef HAVE_PREAD
int
error
=
0
;
int
error
=
0
;
off_t
old_offset
;
o
s_o
ff_t
old_offset
;
writenbytes
=
(
uint
)
-
1
;
writenbytes
=
(
uint
)
-
1
;
pthread_mutex_lock
(
&
my_file_info
[
Filedes
].
mutex
);
pthread_mutex_lock
(
&
my_file_info
[
Filedes
].
mutex
);
...
@@ -124,7 +124,7 @@ uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset,
...
@@ -124,7 +124,7 @@ uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset,
As we cannot change the file pointer, we save the old position,
As we cannot change the file pointer, we save the old position,
before seeking to the given offset
before seeking to the given offset
*/
*/
error
=
((
old_offset
=
(
off_t
)
lseek
(
Filedes
,
0L
,
MY_SEEK_CUR
))
==
-
1L
||
error
=
((
old_offset
=
lseek
(
Filedes
,
0L
,
MY_SEEK_CUR
))
==
-
1L
||
lseek
(
Filedes
,
offset
,
MY_SEEK_SET
)
==
-
1L
);
lseek
(
Filedes
,
offset
,
MY_SEEK_SET
)
==
-
1L
);
if
(
!
error
)
/* Seek was successful */
if
(
!
error
)
/* Seek was successful */
...
...
mysys/my_pthread.c
View file @
8ad2472e
...
@@ -29,8 +29,6 @@
...
@@ -29,8 +29,6 @@
#define SCHED_POLICY SCHED_OTHER
#define SCHED_POLICY SCHED_OTHER
#endif
#endif
uint
thd_lib_detected
=
0
;
uint
thd_lib_detected
;
uint
thd_lib_detected
;
#ifndef my_pthread_setprio
#ifndef my_pthread_setprio
...
...
mysys/my_redel.c
View file @
8ad2472e
...
@@ -59,7 +59,7 @@ int my_redel(const char *org_name, const char *tmp_name, myf MyFlags)
...
@@ -59,7 +59,7 @@ int my_redel(const char *org_name, const char *tmp_name, myf MyFlags)
MyFlags
))
MyFlags
))
goto
end
;
goto
end
;
}
}
else
if
(
my_delete
(
org_name
,
MyFlags
))
else
if
(
my_delete
_allow_opened
(
org_name
,
MyFlags
))
goto
end
;
goto
end
;
if
(
my_rename
(
tmp_name
,
org_name
,
MyFlags
))
if
(
my_rename
(
tmp_name
,
org_name
,
MyFlags
))
goto
end
;
goto
end
;
...
...
sql/mysql_priv.h
View file @
8ad2472e
...
@@ -1445,6 +1445,9 @@ void close_system_tables(THD *thd, Open_tables_state *backup);
...
@@ -1445,6 +1445,9 @@ void close_system_tables(THD *thd, Open_tables_state *backup);
TABLE
*
open_system_table_for_update
(
THD
*
thd
,
TABLE_LIST
*
one_table
);
TABLE
*
open_system_table_for_update
(
THD
*
thd
,
TABLE_LIST
*
one_table
);
bool
close_cached_tables
(
THD
*
thd
,
bool
wait_for_refresh
,
TABLE_LIST
*
tables
,
bool
have_lock
=
FALSE
);
bool
close_cached_tables
(
THD
*
thd
,
bool
wait_for_refresh
,
TABLE_LIST
*
tables
,
bool
have_lock
=
FALSE
);
bool
close_cached_connection_tables
(
THD
*
thd
,
bool
wait_for_refresh
,
LEX_STRING
*
connect_string
,
bool
have_lock
=
FALSE
);
void
copy_field_from_tmp_record
(
Field
*
field
,
int
offset
);
void
copy_field_from_tmp_record
(
Field
*
field
,
int
offset
);
bool
fill_record
(
THD
*
thd
,
Field
**
field
,
List
<
Item
>
&
values
,
bool
fill_record
(
THD
*
thd
,
Field
**
field
,
List
<
Item
>
&
values
,
bool
ignore_errors
);
bool
ignore_errors
);
...
...
sql/sql_base.cc
View file @
8ad2472e
...
@@ -858,6 +858,7 @@ void free_io_cache(TABLE *table)
...
@@ -858,6 +858,7 @@ void free_io_cache(TABLE *table)
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
/*
/*
Close all tables which aren't in use by any thread
Close all tables which aren't in use by any thread
...
@@ -969,6 +970,71 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
...
@@ -969,6 +970,71 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
}
}
/*
Close all tables which match specified connection string or
if specified string is NULL, then any table with a connection string.
*/
bool
close_cached_connection_tables
(
THD
*
thd
,
bool
if_wait_for_refresh
,
LEX_STRING
*
connection
,
bool
have_lock
)
{
uint
idx
;
TABLE_LIST
tmp
,
*
tables
=
NULL
;
bool
result
=
FALSE
;
DBUG_ENTER
(
"close_cached_connections"
);
DBUG_ASSERT
(
thd
);
bzero
(
&
tmp
,
sizeof
(
TABLE_LIST
));
if
(
!
have_lock
)
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
for
(
idx
=
0
;
idx
<
table_def_cache
.
records
;
idx
++
)
{
TABLE_SHARE
*
share
=
(
TABLE_SHARE
*
)
hash_element
(
&
table_def_cache
,
idx
);
/* Ignore if table is not open or does not have a connect_string */
if
(
!
share
->
connect_string
.
length
||
!
share
->
ref_count
)
continue
;
/* Compare the connection string */
if
(
connection
&&
(
connection
->
length
>
share
->
connect_string
.
length
||
(
connection
->
length
<
share
->
connect_string
.
length
&&
(
share
->
connect_string
.
str
[
connection
->
length
]
!=
'/'
&&
share
->
connect_string
.
str
[
connection
->
length
]
!=
'\\'
))
||
strncasecmp
(
connection
->
str
,
share
->
connect_string
.
str
,
connection
->
length
)))
continue
;
/* close_cached_tables() only uses these elements */
tmp
.
db
=
share
->
db
.
str
;
tmp
.
table_name
=
share
->
table_name
.
str
;
tmp
.
next_local
=
tables
;
tables
=
(
TABLE_LIST
*
)
memdup_root
(
thd
->
mem_root
,
(
char
*
)
&
tmp
,
sizeof
(
TABLE_LIST
));
}
if
(
tables
)
result
=
close_cached_tables
(
thd
,
FALSE
,
tables
,
TRUE
);
if
(
!
have_lock
)
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
if
(
if_wait_for_refresh
)
{
pthread_mutex_lock
(
&
thd
->
mysys_var
->
mutex
);
thd
->
mysys_var
->
current_mutex
=
0
;
thd
->
mysys_var
->
current_cond
=
0
;
thd
->
proc_info
=
0
;
pthread_mutex_unlock
(
&
thd
->
mysys_var
->
mutex
);
}
DBUG_RETURN
(
result
);
}
/*
/*
Mark all tables in the list which were used by current substatement
Mark all tables in the list which were used by current substatement
as free for reuse.
as free for reuse.
...
...
sql/sql_parse.cc
View file @
8ad2472e
...
@@ -4274,6 +4274,10 @@ create_sp_error:
...
@@ -4274,6 +4274,10 @@ create_sp_error:
int
error
;
int
error
;
LEX
*
lex
=
thd
->
lex
;
LEX
*
lex
=
thd
->
lex
;
DBUG_PRINT
(
"info"
,
(
"case SQLCOM_CREATE_SERVER"
));
DBUG_PRINT
(
"info"
,
(
"case SQLCOM_CREATE_SERVER"
));
if
(
check_global_access
(
thd
,
SUPER_ACL
))
break
;
if
((
error
=
create_server
(
thd
,
&
lex
->
server_options
)))
if
((
error
=
create_server
(
thd
,
&
lex
->
server_options
)))
{
{
DBUG_PRINT
(
"info"
,
(
"problem creating server <%s>"
,
DBUG_PRINT
(
"info"
,
(
"problem creating server <%s>"
,
...
@@ -4289,6 +4293,10 @@ create_sp_error:
...
@@ -4289,6 +4293,10 @@ create_sp_error:
int
error
;
int
error
;
LEX
*
lex
=
thd
->
lex
;
LEX
*
lex
=
thd
->
lex
;
DBUG_PRINT
(
"info"
,
(
"case SQLCOM_ALTER_SERVER"
));
DBUG_PRINT
(
"info"
,
(
"case SQLCOM_ALTER_SERVER"
));
if
(
check_global_access
(
thd
,
SUPER_ACL
))
break
;
if
((
error
=
alter_server
(
thd
,
&
lex
->
server_options
)))
if
((
error
=
alter_server
(
thd
,
&
lex
->
server_options
)))
{
{
DBUG_PRINT
(
"info"
,
(
"problem altering server <%s>"
,
DBUG_PRINT
(
"info"
,
(
"problem altering server <%s>"
,
...
@@ -4304,9 +4312,13 @@ create_sp_error:
...
@@ -4304,9 +4312,13 @@ create_sp_error:
int
err_code
;
int
err_code
;
LEX
*
lex
=
thd
->
lex
;
LEX
*
lex
=
thd
->
lex
;
DBUG_PRINT
(
"info"
,
(
"case SQLCOM_DROP_SERVER"
));
DBUG_PRINT
(
"info"
,
(
"case SQLCOM_DROP_SERVER"
));
if
(
check_global_access
(
thd
,
SUPER_ACL
))
break
;
if
((
err_code
=
drop_server
(
thd
,
&
lex
->
server_options
)))
if
((
err_code
=
drop_server
(
thd
,
&
lex
->
server_options
)))
{
{
if
(
!
lex
->
drop_if_exists
&&
err_code
==
ER_FOREIGN_SERVER_
EXISTS
)
if
(
!
lex
->
drop_if_exists
&&
err_code
==
ER_FOREIGN_SERVER_
DOESNT_EXIST
)
{
{
DBUG_PRINT
(
"info"
,
(
"problem dropping server %s"
,
DBUG_PRINT
(
"info"
,
(
"problem dropping server %s"
,
lex
->
server_options
.
server_name
));
lex
->
server_options
.
server_name
));
...
...
sql/sql_servers.cc
View file @
8ad2472e
...
@@ -16,6 +16,21 @@
...
@@ -16,6 +16,21 @@
/*
/*
The servers are saved in the system table "servers"
The servers are saved in the system table "servers"
Currently, when the user performs an ALTER SERVER or a DROP SERVER
operation, it will cause all open tables which refer to the named
server connection to be flushed. This may cause some undesirable
behaviour with regard to currently running transactions. It is
expected that the DBA knows what s/he is doing when s/he performs
the ALTER SERVER or DROP SERVER operation.
TODO:
It is desirable for us to implement a callback mechanism instead where
callbacks can be registered for specific server protocols. The callback
will be fired when such a server name has been created/altered/dropped
or when statistics are to be gathered such as how many actual connections.
Storage engines etc will be able to make use of the callback so that
currently running transactions etc will not be disrupted.
*/
*/
#include "mysql_priv.h"
#include "mysql_priv.h"
...
@@ -25,15 +40,43 @@
...
@@ -25,15 +40,43 @@
#include "sp_head.h"
#include "sp_head.h"
#include "sp.h"
#include "sp.h"
static
my_bool
servers_load
(
THD
*
thd
,
TABLE_LIST
*
tables
);
/*
HASH
servers_cache
;
We only use 1 mutex to guard the data structures - THR_LOCK_servers.
pthread_mutex_t
servers_cache_mutex
;
// To init the hash
Read locked when only reading data and write-locked for all other access.
uint
servers_cache_initialised
=
FALSE
;
*/
/* Version of server table. incremented by servers_load */
static
uint
servers_version
=
0
;
static
HASH
servers_cache
;
static
MEM_ROOT
mem
;
static
MEM_ROOT
mem
;
static
rw_lock_t
THR_LOCK_servers
;
static
rw_lock_t
THR_LOCK_servers
;
static
bool
get_server_from_table_to_cache
(
TABLE
*
table
);
/* insert functions */
static
int
insert_server
(
THD
*
thd
,
FOREIGN_SERVER
*
server_options
);
static
int
insert_server_record
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
);
static
int
insert_server_record_into_cache
(
FOREIGN_SERVER
*
server
);
static
void
prepare_server_struct_for_insert
(
LEX_SERVER_OPTIONS
*
server_options
,
FOREIGN_SERVER
*
server
);
/* drop functions */
static
int
delete_server_record
(
TABLE
*
table
,
char
*
server_name
,
int
server_name_length
);
static
int
delete_server_record_in_cache
(
LEX_SERVER_OPTIONS
*
server_options
);
/* update functions */
static
void
prepare_server_struct_for_update
(
LEX_SERVER_OPTIONS
*
server_options
,
FOREIGN_SERVER
*
existing
,
FOREIGN_SERVER
*
altered
);
static
int
update_server
(
THD
*
thd
,
FOREIGN_SERVER
*
existing
,
FOREIGN_SERVER
*
altered
);
static
int
update_server_record
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
);
static
int
update_server_record_in_cache
(
FOREIGN_SERVER
*
existing
,
FOREIGN_SERVER
*
altered
);
/* utility functions */
static
void
merge_server_struct
(
FOREIGN_SERVER
*
from
,
FOREIGN_SERVER
*
to
);
static
byte
*
servers_cache_get_key
(
FOREIGN_SERVER
*
server
,
uint
*
length
,
static
byte
*
servers_cache_get_key
(
FOREIGN_SERVER
*
server
,
uint
*
length
,
my_bool
not_used
__attribute__
((
unused
)))
my_bool
not_used
__attribute__
((
unused
)))
{
{
...
@@ -46,6 +89,7 @@ static byte *servers_cache_get_key(FOREIGN_SERVER *server, uint *length,
...
@@ -46,6 +89,7 @@ static byte *servers_cache_get_key(FOREIGN_SERVER *server, uint *length,
DBUG_RETURN
((
byte
*
)
server
->
server_name
);
DBUG_RETURN
((
byte
*
)
server
->
server_name
);
}
}
/*
/*
Initialize structures responsible for servers used in federated
Initialize structures responsible for servers used in federated
server scheme information for them from the server
server scheme information for them from the server
...
@@ -65,35 +109,27 @@ static byte *servers_cache_get_key(FOREIGN_SERVER *server, uint *length,
...
@@ -65,35 +109,27 @@ static byte *servers_cache_get_key(FOREIGN_SERVER *server, uint *length,
1 Could not initialize servers
1 Could not initialize servers
*/
*/
my_
bool
servers_init
(
bool
dont_read_servers_table
)
bool
servers_init
(
bool
dont_read_servers_table
)
{
{
THD
*
thd
;
THD
*
thd
;
my_bool
return_val
=
0
;
bool
return_val
=
FALSE
;
DBUG_ENTER
(
"servers_init"
);
DBUG_ENTER
(
"servers_init"
);
/* init the mutex */
/* init the mutex */
if
(
pthread_mutex_init
(
&
servers_cache_mutex
,
MY_MUTEX_INIT_FAST
))
DBUG_RETURN
(
1
);
if
(
my_rwlock_init
(
&
THR_LOCK_servers
,
NULL
))
if
(
my_rwlock_init
(
&
THR_LOCK_servers
,
NULL
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
TRUE
);
/* initialise our servers cache */
/* initialise our servers cache */
if
(
hash_init
(
&
servers_cache
,
system_charset_info
,
32
,
0
,
0
,
if
(
hash_init
(
&
servers_cache
,
system_charset_info
,
32
,
0
,
0
,
(
hash_get_key
)
servers_cache_get_key
,
0
,
0
))
(
hash_get_key
)
servers_cache_get_key
,
0
,
0
))
{
{
return_val
=
1
;
/* we failed, out of memory? */
return_val
=
TRUE
;
/* we failed, out of memory? */
goto
end
;
goto
end
;
}
}
/* Initialize the mem root for data */
/* Initialize the mem root for data */
init_alloc_root
(
&
mem
,
ACL_ALLOC_BLOCK_SIZE
,
0
);
init_alloc_root
(
&
mem
,
ACL_ALLOC_BLOCK_SIZE
,
0
);
/*
at this point, the cache is initialised, let it be known
*/
servers_cache_initialised
=
TRUE
;
if
(
dont_read_servers_table
)
if
(
dont_read_servers_table
)
goto
end
;
goto
end
;
...
@@ -101,7 +137,7 @@ my_bool servers_init(bool dont_read_servers_table)
...
@@ -101,7 +137,7 @@ my_bool servers_init(bool dont_read_servers_table)
To be able to run this from boot, we allocate a temporary THD
To be able to run this from boot, we allocate a temporary THD
*/
*/
if
(
!
(
thd
=
new
THD
))
if
(
!
(
thd
=
new
THD
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
TRUE
);
thd
->
thread_stack
=
(
char
*
)
&
thd
;
thd
->
thread_stack
=
(
char
*
)
&
thd
;
thd
->
store_globals
();
thd
->
store_globals
();
/*
/*
...
@@ -131,19 +167,13 @@ end:
...
@@ -131,19 +167,13 @@ end:
TRUE Error
TRUE Error
*/
*/
static
my_
bool
servers_load
(
THD
*
thd
,
TABLE_LIST
*
tables
)
static
bool
servers_load
(
THD
*
thd
,
TABLE_LIST
*
tables
)
{
{
TABLE
*
table
;
TABLE
*
table
;
READ_RECORD
read_record_info
;
READ_RECORD
read_record_info
;
my_
bool
return_val
=
TRUE
;
bool
return_val
=
TRUE
;
DBUG_ENTER
(
"servers_load"
);
DBUG_ENTER
(
"servers_load"
);
if
(
!
servers_cache_initialised
)
DBUG_RETURN
(
0
);
/* need to figure out how to utilise this variable */
servers_version
++
;
/* servers updated */
/* first, send all cached rows to sleep with the fishes, oblivion!
/* first, send all cached rows to sleep with the fishes, oblivion!
I expect this crappy comment replaced */
I expect this crappy comment replaced */
free_root
(
&
mem
,
MYF
(
MY_MARK_BLOCKS_FREE
));
free_root
(
&
mem
,
MYF
(
MY_MARK_BLOCKS_FREE
));
...
@@ -157,7 +187,7 @@ static my_bool servers_load(THD *thd, TABLE_LIST *tables)
...
@@ -157,7 +187,7 @@ static my_bool servers_load(THD *thd, TABLE_LIST *tables)
goto
end
;
goto
end
;
}
}
return_val
=
0
;
return_val
=
FALSE
;
end:
end:
end_read_record
(
&
read_record_info
);
end_read_record
(
&
read_record_info
);
...
@@ -184,10 +214,10 @@ end:
...
@@ -184,10 +214,10 @@ end:
TRUE Failure
TRUE Failure
*/
*/
my_
bool
servers_reload
(
THD
*
thd
)
bool
servers_reload
(
THD
*
thd
)
{
{
TABLE_LIST
tables
[
1
];
TABLE_LIST
tables
[
1
];
my_bool
return_val
=
1
;
bool
return_val
=
TRUE
;
DBUG_ENTER
(
"servers_reload"
);
DBUG_ENTER
(
"servers_reload"
);
if
(
thd
->
locked_tables
)
if
(
thd
->
locked_tables
)
...
@@ -197,10 +227,9 @@ my_bool servers_reload(THD *thd)
...
@@ -197,10 +227,9 @@ my_bool servers_reload(THD *thd)
close_thread_tables
(
thd
);
close_thread_tables
(
thd
);
}
}
/*
DBUG_PRINT
(
"info"
,
(
"locking servers_cache"
));
To avoid deadlocks we should obtain table locks before
rw_wrlock
(
&
THR_LOCK_servers
);
obtaining servers_cache->lock mutex.
*/
bzero
((
char
*
)
tables
,
sizeof
(
tables
));
bzero
((
char
*
)
tables
,
sizeof
(
tables
));
tables
[
0
].
alias
=
tables
[
0
].
table_name
=
(
char
*
)
"servers"
;
tables
[
0
].
alias
=
tables
[
0
].
table_name
=
(
char
*
)
"servers"
;
tables
[
0
].
db
=
(
char
*
)
"mysql"
;
tables
[
0
].
db
=
(
char
*
)
"mysql"
;
...
@@ -213,12 +242,6 @@ my_bool servers_reload(THD *thd)
...
@@ -213,12 +242,6 @@ my_bool servers_reload(THD *thd)
goto
end
;
goto
end
;
}
}
DBUG_PRINT
(
"info"
,
(
"locking servers_cache"
));
VOID
(
pthread_mutex_lock
(
&
servers_cache_mutex
));
//old_servers_cache= servers_cache;
//old_mem=mem;
if
((
return_val
=
servers_load
(
thd
,
tables
)))
if
((
return_val
=
servers_load
(
thd
,
tables
)))
{
// Error. Revert to old list
{
// Error. Revert to old list
/* blast, for now, we have no servers, discuss later way to preserve */
/* blast, for now, we have no servers, discuss later way to preserve */
...
@@ -227,14 +250,14 @@ my_bool servers_reload(THD *thd)
...
@@ -227,14 +250,14 @@ my_bool servers_reload(THD *thd)
servers_free
();
servers_free
();
}
}
DBUG_PRINT
(
"info"
,
(
"unlocking servers_cache"
));
VOID
(
pthread_mutex_unlock
(
&
servers_cache_mutex
));
end:
end:
close_thread_tables
(
thd
);
close_thread_tables
(
thd
);
DBUG_PRINT
(
"info"
,
(
"unlocking servers_cache"
));
rw_unlock
(
&
THR_LOCK_servers
);
DBUG_RETURN
(
return_val
);
DBUG_RETURN
(
return_val
);
}
}
/*
/*
Initialize structures responsible for servers used in federated
Initialize structures responsible for servers used in federated
server scheme information for them from the server
server scheme information for them from the server
...
@@ -261,7 +284,8 @@ end:
...
@@ -261,7 +284,8 @@ end:
1 could not insert server struct into global servers cache
1 could not insert server struct into global servers cache
*/
*/
my_bool
get_server_from_table_to_cache
(
TABLE
*
table
)
static
bool
get_server_from_table_to_cache
(
TABLE
*
table
)
{
{
/* alloc a server struct */
/* alloc a server struct */
char
*
ptr
;
char
*
ptr
;
...
@@ -309,68 +333,6 @@ my_bool get_server_from_table_to_cache(TABLE *table)
...
@@ -309,68 +333,6 @@ my_bool get_server_from_table_to_cache(TABLE *table)
DBUG_RETURN
(
FALSE
);
DBUG_RETURN
(
FALSE
);
}
}
/*
SYNOPSIS
server_exists_in_table()
THD *thd - thread pointer
LEX_SERVER_OPTIONS *server_options - pointer to Lex->server_options
NOTES
This function takes a LEX_SERVER_OPTIONS struct, which is very much the
same type of structure as a FOREIGN_SERVER, it contains the values parsed
in any one of the [CREATE|DELETE|DROP] SERVER statements. Using the
member "server_name", index_read_idx either founds the record and returns
1, or doesn't find the record, and returns 0
RETURN VALUES
0 record not found
1 record found
*/
my_bool
server_exists_in_table
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
)
{
int
result
=
1
;
int
error
=
0
;
TABLE_LIST
tables
;
TABLE
*
table
;
DBUG_ENTER
(
"server_exists"
);
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
tables
.
db
=
(
char
*
)
"mysql"
;
tables
.
alias
=
tables
.
table_name
=
(
char
*
)
"servers"
;
/* need to open before acquiring THR_LOCK_plugin or it will deadlock */
if
(
!
(
table
=
open_ltable
(
thd
,
&
tables
,
TL_WRITE
)))
DBUG_RETURN
(
TRUE
);
table
->
use_all_columns
();
rw_wrlock
(
&
THR_LOCK_servers
);
VOID
(
pthread_mutex_lock
(
&
servers_cache_mutex
));
/* set the field that's the PK to the value we're looking for */
table
->
field
[
0
]
->
store
(
server_options
->
server_name
,
server_options
->
server_name_length
,
system_charset_info
);
if
((
error
=
table
->
file
->
index_read_idx
(
table
->
record
[
0
],
0
,
(
byte
*
)
table
->
field
[
0
]
->
ptr
,
HA_WHOLE_KEY
,
HA_READ_KEY_EXACT
)))
{
if
(
error
!=
HA_ERR_KEY_NOT_FOUND
&&
error
!=
HA_ERR_END_OF_FILE
)
{
table
->
file
->
print_error
(
error
,
MYF
(
0
));
result
=
-
1
;
}
result
=
0
;
DBUG_PRINT
(
"info"
,(
"record for server '%s' not found!"
,
server_options
->
server_name
));
}
VOID
(
pthread_mutex_unlock
(
&
servers_cache_mutex
));
rw_unlock
(
&
THR_LOCK_servers
);
DBUG_RETURN
(
result
);
}
/*
/*
SYNOPSIS
SYNOPSIS
...
@@ -383,14 +345,17 @@ my_bool server_exists_in_table(THD *thd, LEX_SERVER_OPTIONS *server_options)
...
@@ -383,14 +345,17 @@ my_bool server_exists_in_table(THD *thd, LEX_SERVER_OPTIONS *server_options)
prepared, ready to be inserted both into the mysql.servers table and
prepared, ready to be inserted both into the mysql.servers table and
the servers cache.
the servers cache.
THR_LOCK_servers must be write locked.
RETURN VALUES
RETURN VALUES
0 - no error
0 - no error
other - error code
other - error code
*/
*/
int
insert_server
(
THD
*
thd
,
FOREIGN_SERVER
*
server
)
static
int
insert_server
(
THD
*
thd
,
FOREIGN_SERVER
*
server
)
{
{
int
error
=
0
;
int
error
=
-
1
;
TABLE_LIST
tables
;
TABLE_LIST
tables
;
TABLE
*
table
;
TABLE
*
table
;
...
@@ -402,13 +367,7 @@ int insert_server(THD *thd, FOREIGN_SERVER *server)
...
@@ -402,13 +367,7 @@ int insert_server(THD *thd, FOREIGN_SERVER *server)
/* need to open before acquiring THR_LOCK_plugin or it will deadlock */
/* need to open before acquiring THR_LOCK_plugin or it will deadlock */
if
(
!
(
table
=
open_ltable
(
thd
,
&
tables
,
TL_WRITE
)))
if
(
!
(
table
=
open_ltable
(
thd
,
&
tables
,
TL_WRITE
)))
DBUG_RETURN
(
TRUE
);
goto
end
;
/* lock mutex to make sure no changes happen */
VOID
(
pthread_mutex_lock
(
&
servers_cache_mutex
));
/* lock table */
rw_wrlock
(
&
THR_LOCK_servers
);
/* insert the server into the table */
/* insert the server into the table */
if
((
error
=
insert_server_record
(
table
,
server
)))
if
((
error
=
insert_server_record
(
table
,
server
)))
...
@@ -419,12 +378,10 @@ int insert_server(THD *thd, FOREIGN_SERVER *server)
...
@@ -419,12 +378,10 @@ int insert_server(THD *thd, FOREIGN_SERVER *server)
goto
end
;
goto
end
;
end:
end:
/* unlock the table */
rw_unlock
(
&
THR_LOCK_servers
);
VOID
(
pthread_mutex_unlock
(
&
servers_cache_mutex
));
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
/*
/*
SYNOPSIS
SYNOPSIS
int insert_server_record_into_cache()
int insert_server_record_into_cache()
...
@@ -434,13 +391,16 @@ end:
...
@@ -434,13 +391,16 @@ end:
This function takes a FOREIGN_SERVER pointer to an allocated (root mem)
This function takes a FOREIGN_SERVER pointer to an allocated (root mem)
and inserts it into the global servers cache
and inserts it into the global servers cache
THR_LOCK_servers must be write locked.
RETURN VALUE
RETURN VALUE
0 - no error
0 - no error
>0 - error code
>0 - error code
*/
*/
int
insert_server_record_into_cache
(
FOREIGN_SERVER
*
server
)
static
int
insert_server_record_into_cache
(
FOREIGN_SERVER
*
server
)
{
{
int
error
=
0
;
int
error
=
0
;
DBUG_ENTER
(
"insert_server_record_into_cache"
);
DBUG_ENTER
(
"insert_server_record_into_cache"
);
...
@@ -461,6 +421,7 @@ int insert_server_record_into_cache(FOREIGN_SERVER *server)
...
@@ -461,6 +421,7 @@ int insert_server_record_into_cache(FOREIGN_SERVER *server)
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
/*
/*
SYNOPSIS
SYNOPSIS
store_server_fields()
store_server_fields()
...
@@ -478,7 +439,8 @@ int insert_server_record_into_cache(FOREIGN_SERVER *server)
...
@@ -478,7 +439,8 @@ int insert_server_record_into_cache(FOREIGN_SERVER *server)
*/
*/
void
store_server_fields
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
)
static
void
store_server_fields
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
)
{
{
table
->
use_all_columns
();
table
->
use_all_columns
();
...
@@ -539,6 +501,7 @@ void store_server_fields(TABLE *table, FOREIGN_SERVER *server)
...
@@ -539,6 +501,7 @@ void store_server_fields(TABLE *table, FOREIGN_SERVER *server)
*/
*/
static
int
insert_server_record
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
)
int
insert_server_record
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
)
{
{
int
error
;
int
error
;
...
@@ -605,9 +568,11 @@ int insert_server_record(TABLE *table, FOREIGN_SERVER *server)
...
@@ -605,9 +568,11 @@ int insert_server_record(TABLE *table, FOREIGN_SERVER *server)
int
drop_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
)
int
drop_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
)
{
{
int
error
=
0
;
int
error
;
TABLE_LIST
tables
;
TABLE_LIST
tables
;
TABLE
*
table
;
TABLE
*
table
;
LEX_STRING
name
=
{
server_options
->
server_name
,
server_options
->
server_name_length
};
DBUG_ENTER
(
"drop_server"
);
DBUG_ENTER
(
"drop_server"
);
DBUG_PRINT
(
"info"
,
(
"server name server->server_name %s"
,
DBUG_PRINT
(
"info"
,
(
"server name server->server_name %s"
,
...
@@ -617,28 +582,35 @@ int drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
...
@@ -617,28 +582,35 @@ int drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
tables
.
db
=
(
char
*
)
"mysql"
;
tables
.
db
=
(
char
*
)
"mysql"
;
tables
.
alias
=
tables
.
table_name
=
(
char
*
)
"servers"
;
tables
.
alias
=
tables
.
table_name
=
(
char
*
)
"servers"
;
/* need to open before acquiring THR_LOCK_plugin or it will deadlock */
if
(
!
(
table
=
open_ltable
(
thd
,
&
tables
,
TL_WRITE
)))
DBUG_RETURN
(
TRUE
);
rw_wrlock
(
&
THR_LOCK_servers
);
rw_wrlock
(
&
THR_LOCK_servers
);
VOID
(
pthread_mutex_lock
(
&
servers_cache_mutex
));
/* hit the memory hit first */
if
((
error
=
delete_server_record_in_cache
(
server_options
)))
goto
end
;
if
(
(
error
=
delete_server_record
(
table
,
if
(
!
(
table
=
open_ltable
(
thd
,
&
tables
,
TL_WRITE
)))
server_options
->
server_name
,
{
server_options
->
server_name_length
)))
error
=
my_errno
;
goto
end
;
goto
end
;
}
error
=
delete_server_record
(
table
,
name
.
str
,
name
.
length
);
if
((
error
=
delete_server_record_in_cache
(
server_options
)))
/* close the servers table before we call closed_cached_connection_tables */
goto
end
;
close_thread_tables
(
thd
);
if
(
close_cached_connection_tables
(
thd
,
TRUE
,
&
name
))
{
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_UNKNOWN_ERROR
,
"Server connection in use"
);
}
end:
end:
VOID
(
pthread_mutex_unlock
(
&
servers_cache_mutex
));
rw_unlock
(
&
THR_LOCK_servers
);
rw_unlock
(
&
THR_LOCK_servers
);
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
/*
/*
SYNOPSIS
SYNOPSIS
...
@@ -657,10 +629,10 @@ end:
...
@@ -657,10 +629,10 @@ end:
*/
*/
int
delete_server_record_in_cache
(
LEX_SERVER_OPTIONS
*
server_options
)
static
int
delete_server_record_in_cache
(
LEX_SERVER_OPTIONS
*
server_options
)
{
{
int
error
=
ER_FOREIGN_SERVER_DOESNT_EXIST
;
int
error
=
0
;
FOREIGN_SERVER
*
server
;
FOREIGN_SERVER
*
server
;
DBUG_ENTER
(
"delete_server_record_in_cache"
);
DBUG_ENTER
(
"delete_server_record_in_cache"
);
...
@@ -676,7 +648,7 @@ int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options)
...
@@ -676,7 +648,7 @@ int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options)
DBUG_PRINT
(
"info"
,
(
"server_name %s length %d not found!"
,
DBUG_PRINT
(
"info"
,
(
"server_name %s length %d not found!"
,
server_options
->
server_name
,
server_options
->
server_name
,
server_options
->
server_name_length
));
server_options
->
server_name_length
));
// what should be done if not found in the cache?
goto
end
;
}
}
/*
/*
We succeded in deletion of the server to the table, now delete
We succeded in deletion of the server to the table, now delete
...
@@ -686,14 +658,15 @@ int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options)
...
@@ -686,14 +658,15 @@ int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options)
server
->
server_name
,
server
->
server_name
,
server
->
server_name_length
));
server
->
server_name_length
));
if
(
server
)
VOID
(
hash_delete
(
&
servers_cache
,
(
byte
*
)
server
));
VOID
(
hash_delete
(
&
servers_cache
,
(
byte
*
)
server
));
servers_version
++
;
/* servers updated */
error
=
0
;
end:
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
/*
/*
SYNOPSIS
SYNOPSIS
...
@@ -713,6 +686,8 @@ int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options)
...
@@ -713,6 +686,8 @@ int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options)
table for the particular server via the call to update_server_record,
table for the particular server via the call to update_server_record,
and in the servers_cache via update_server_record_in_cache.
and in the servers_cache via update_server_record_in_cache.
THR_LOCK_servers must be write locked.
RETURN VALUE
RETURN VALUE
0 - no error
0 - no error
>0 - error code
>0 - error code
...
@@ -721,7 +696,7 @@ int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options)
...
@@ -721,7 +696,7 @@ int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options)
int
update_server
(
THD
*
thd
,
FOREIGN_SERVER
*
existing
,
FOREIGN_SERVER
*
altered
)
int
update_server
(
THD
*
thd
,
FOREIGN_SERVER
*
existing
,
FOREIGN_SERVER
*
altered
)
{
{
int
error
=
0
;
int
error
;
TABLE
*
table
;
TABLE
*
table
;
TABLE_LIST
tables
;
TABLE_LIST
tables
;
DBUG_ENTER
(
"update_server"
);
DBUG_ENTER
(
"update_server"
);
...
@@ -731,19 +706,26 @@ int update_server(THD *thd, FOREIGN_SERVER *existing, FOREIGN_SERVER *altered)
...
@@ -731,19 +706,26 @@ int update_server(THD *thd, FOREIGN_SERVER *existing, FOREIGN_SERVER *altered)
tables
.
alias
=
tables
.
table_name
=
(
char
*
)
"servers"
;
tables
.
alias
=
tables
.
table_name
=
(
char
*
)
"servers"
;
if
(
!
(
table
=
open_ltable
(
thd
,
&
tables
,
TL_WRITE
)))
if
(
!
(
table
=
open_ltable
(
thd
,
&
tables
,
TL_WRITE
)))
DBUG_RETURN
(
1
);
{
error
=
my_errno
;
goto
end
;
}
rw_wrlock
(
&
THR_LOCK_servers
);
if
((
error
=
update_server_record
(
table
,
altered
)))
if
((
error
=
update_server_record
(
table
,
altered
)))
goto
end
;
goto
end
;
update_server_record_in_cache
(
existing
,
altered
);
error
=
update_server_record_in_cache
(
existing
,
altered
);
/*
Perform a reload so we don't have a 'hole' in our mem_root
*/
servers_load
(
thd
,
&
tables
);
end:
end:
rw_unlock
(
&
THR_LOCK_servers
);
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
/*
/*
SYNOPSIS
SYNOPSIS
...
@@ -760,6 +742,8 @@ end:
...
@@ -760,6 +742,8 @@ end:
HASH, then the updated record inserted, in essence replacing the old
HASH, then the updated record inserted, in essence replacing the old
record.
record.
THR_LOCK_servers must be write locked.
RETURN VALUE
RETURN VALUE
0 - no error
0 - no error
1 - error
1 - error
...
@@ -790,13 +774,13 @@ int update_server_record_in_cache(FOREIGN_SERVER *existing,
...
@@ -790,13 +774,13 @@ int update_server_record_in_cache(FOREIGN_SERVER *existing,
{
{
DBUG_PRINT
(
"info"
,
(
"had a problem inserting server %s at %lx"
,
DBUG_PRINT
(
"info"
,
(
"had a problem inserting server %s at %lx"
,
altered
->
server_name
,
(
long
unsigned
int
)
altered
));
altered
->
server_name
,
(
long
unsigned
int
)
altered
));
error
=
1
;
error
=
ER_OUT_OF_RESOURCES
;
}
}
servers_version
++
;
/* servers updated */
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
/*
/*
SYNOPSIS
SYNOPSIS
...
@@ -829,9 +813,9 @@ void merge_server_struct(FOREIGN_SERVER *from, FOREIGN_SERVER *to)
...
@@ -829,9 +813,9 @@ void merge_server_struct(FOREIGN_SERVER *from, FOREIGN_SERVER *to)
to
->
password
=
strdup_root
(
&
mem
,
from
->
password
);
to
->
password
=
strdup_root
(
&
mem
,
from
->
password
);
if
(
to
->
port
==
-
1
)
if
(
to
->
port
==
-
1
)
to
->
port
=
from
->
port
;
to
->
port
=
from
->
port
;
if
(
!
to
->
socket
)
if
(
!
to
->
socket
&&
from
->
socket
)
to
->
socket
=
strdup_root
(
&
mem
,
from
->
socket
);
to
->
socket
=
strdup_root
(
&
mem
,
from
->
socket
);
if
(
!
to
->
scheme
)
if
(
!
to
->
scheme
&&
from
->
scheme
)
to
->
scheme
=
strdup_root
(
&
mem
,
from
->
scheme
);
to
->
scheme
=
strdup_root
(
&
mem
,
from
->
scheme
);
if
(
!
to
->
owner
)
if
(
!
to
->
owner
)
to
->
owner
=
strdup_root
(
&
mem
,
from
->
owner
);
to
->
owner
=
strdup_root
(
&
mem
,
from
->
owner
);
...
@@ -839,6 +823,7 @@ void merge_server_struct(FOREIGN_SERVER *from, FOREIGN_SERVER *to)
...
@@ -839,6 +823,7 @@ void merge_server_struct(FOREIGN_SERVER *from, FOREIGN_SERVER *to)
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
/*
/*
SYNOPSIS
SYNOPSIS
...
@@ -861,7 +846,9 @@ void merge_server_struct(FOREIGN_SERVER *from, FOREIGN_SERVER *to)
...
@@ -861,7 +846,9 @@ void merge_server_struct(FOREIGN_SERVER *from, FOREIGN_SERVER *to)
*/
*/
int
update_server_record
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
)
static
int
update_server_record
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
)
{
{
int
error
=
0
;
int
error
=
0
;
DBUG_ENTER
(
"update_server_record"
);
DBUG_ENTER
(
"update_server_record"
);
...
@@ -876,10 +863,7 @@ int update_server_record(TABLE *table, FOREIGN_SERVER *server)
...
@@ -876,10 +863,7 @@ int update_server_record(TABLE *table, FOREIGN_SERVER *server)
HA_READ_KEY_EXACT
)))
HA_READ_KEY_EXACT
)))
{
{
if
(
error
!=
HA_ERR_KEY_NOT_FOUND
&&
error
!=
HA_ERR_END_OF_FILE
)
if
(
error
!=
HA_ERR_KEY_NOT_FOUND
&&
error
!=
HA_ERR_END_OF_FILE
)
{
table
->
file
->
print_error
(
error
,
MYF
(
0
));
table
->
file
->
print_error
(
error
,
MYF
(
0
));
error
=
1
;
}
DBUG_PRINT
(
"info"
,(
"server not found!"
));
DBUG_PRINT
(
"info"
,(
"server not found!"
));
error
=
ER_FOREIGN_SERVER_DOESNT_EXIST
;
error
=
ER_FOREIGN_SERVER_DOESNT_EXIST
;
}
}
...
@@ -899,6 +883,7 @@ end:
...
@@ -899,6 +883,7 @@ end:
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
/*
/*
SYNOPSIS
SYNOPSIS
...
@@ -914,11 +899,11 @@ end:
...
@@ -914,11 +899,11 @@ end:
*/
*/
int
delete_server_record
(
TABLE
*
table
,
static
int
char
*
server_nam
e
,
delete_server_record
(
TABLE
*
tabl
e
,
int
server_name_length
)
char
*
server_name
,
int
server_name_length
)
{
{
int
error
=
0
;
int
error
;
DBUG_ENTER
(
"delete_server_record"
);
DBUG_ENTER
(
"delete_server_record"
);
table
->
use_all_columns
();
table
->
use_all_columns
();
...
@@ -930,10 +915,7 @@ int delete_server_record(TABLE *table,
...
@@ -930,10 +915,7 @@ int delete_server_record(TABLE *table,
HA_READ_KEY_EXACT
)))
HA_READ_KEY_EXACT
)))
{
{
if
(
error
!=
HA_ERR_KEY_NOT_FOUND
&&
error
!=
HA_ERR_END_OF_FILE
)
if
(
error
!=
HA_ERR_KEY_NOT_FOUND
&&
error
!=
HA_ERR_END_OF_FILE
)
{
table
->
file
->
print_error
(
error
,
MYF
(
0
));
table
->
file
->
print_error
(
error
,
MYF
(
0
));
error
=
1
;
}
DBUG_PRINT
(
"info"
,(
"server not found!"
));
DBUG_PRINT
(
"info"
,(
"server not found!"
));
error
=
ER_FOREIGN_SERVER_DOESNT_EXIST
;
error
=
ER_FOREIGN_SERVER_DOESNT_EXIST
;
}
}
...
@@ -962,28 +944,35 @@ int delete_server_record(TABLE *table,
...
@@ -962,28 +944,35 @@ int delete_server_record(TABLE *table,
int
create_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
)
int
create_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
)
{
{
int
error
;
int
error
=
ER_FOREIGN_SERVER_EXISTS
;
FOREIGN_SERVER
*
server
;
FOREIGN_SERVER
*
server
;
DBUG_ENTER
(
"create_server"
);
DBUG_ENTER
(
"create_server"
);
DBUG_PRINT
(
"info"
,
(
"server_options->server_name %s"
,
DBUG_PRINT
(
"info"
,
(
"server_options->server_name %s"
,
server_options
->
server_name
));
server_options
->
server_name
));
rw_wrlock
(
&
THR_LOCK_servers
);
/* hit the memory first */
if
(
hash_search
(
&
servers_cache
,
(
byte
*
)
server_options
->
server_name
,
server_options
->
server_name_length
))
goto
end
;
server
=
(
FOREIGN_SERVER
*
)
alloc_root
(
&
mem
,
server
=
(
FOREIGN_SERVER
*
)
alloc_root
(
&
mem
,
sizeof
(
FOREIGN_SERVER
));
sizeof
(
FOREIGN_SERVER
));
if
((
error
=
prepare_server_struct_for_insert
(
server_options
,
server
)))
prepare_server_struct_for_insert
(
server_options
,
server
);
goto
end
;
if
((
error
=
insert_server
(
thd
,
server
)))
error
=
insert_server
(
thd
,
server
);
goto
end
;
DBUG_PRINT
(
"info"
,
(
"error returned %d"
,
error
));
DBUG_PRINT
(
"info"
,
(
"error returned %d"
,
error
));
end:
end:
rw_unlock
(
&
THR_LOCK_servers
);
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
/*
/*
SYNOPSIS
SYNOPSIS
...
@@ -1000,37 +989,44 @@ end:
...
@@ -1000,37 +989,44 @@ end:
int
alter_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
)
int
alter_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
)
{
{
int
error
=
0
;
int
error
=
ER_FOREIGN_SERVER_DOESNT_EXIST
;
FOREIGN_SERVER
*
altered
,
*
existing
;
FOREIGN_SERVER
*
altered
,
*
existing
;
LEX_STRING
name
=
{
server_options
->
server_name
,
server_options
->
server_name_length
};
DBUG_ENTER
(
"alter_server"
);
DBUG_ENTER
(
"alter_server"
);
DBUG_PRINT
(
"info"
,
(
"server_options->server_name %s"
,
DBUG_PRINT
(
"info"
,
(
"server_options->server_name %s"
,
server_options
->
server_name
));
server_options
->
server_name
));
rw_wrlock
(
&
THR_LOCK_servers
);
if
(
!
(
existing
=
(
FOREIGN_SERVER
*
)
hash_search
(
&
servers_cache
,
(
byte
*
)
name
.
str
,
name
.
length
)))
goto
end
;
altered
=
(
FOREIGN_SERVER
*
)
alloc_root
(
&
mem
,
altered
=
(
FOREIGN_SERVER
*
)
alloc_root
(
&
mem
,
sizeof
(
FOREIGN_SERVER
));
sizeof
(
FOREIGN_SERVER
));
VOID
(
pthread_mutex_lock
(
&
servers_cache_mutex
)
);
prepare_server_struct_for_update
(
server_options
,
existing
,
altered
);
if
(
!
(
existing
=
(
FOREIGN_SERVER
*
)
hash_search
(
&
servers_cache
,
error
=
update_server
(
thd
,
existing
,
altered
);
(
byte
*
)
server_options
->
server_name
,
server_options
->
server_name_length
)))
{
error
=
ER_FOREIGN_SERVER_DOESNT_EXIST
;
goto
end
;
}
if
((
error
=
prepare_server_struct_for_update
(
server_options
,
existing
,
altered
)))
/* close the servers table before we call closed_cached_connection_tables */
goto
end
;
close_thread_tables
(
thd
)
;
if
((
error
=
update_server
(
thd
,
existing
,
altered
)))
if
(
close_cached_connection_tables
(
thd
,
FALSE
,
&
name
))
goto
end
;
{
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_UNKNOWN_ERROR
,
"Server connection in use"
);
}
end:
end:
DBUG_PRINT
(
"info"
,
(
"error returned %d"
,
error
));
DBUG_PRINT
(
"info"
,
(
"error returned %d"
,
error
));
VOID
(
pthread_mutex_unlock
(
&
servers_cache_mutex
)
);
rw_unlock
(
&
THR_LOCK_servers
);
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
/*
/*
SYNOPSIS
SYNOPSIS
...
@@ -1041,19 +1037,17 @@ end:
...
@@ -1041,19 +1037,17 @@ end:
NOTES
NOTES
RETURN VALUE
RETURN VALUE
0 - no error
none
*/
*/
int
prepare_server_struct_for_insert
(
LEX_SERVER_OPTIONS
*
server_options
,
static
void
prepare_server_struct_for_insert
(
LEX_SERVER_OPTIONS
*
server_options
,
FOREIGN_SERVER
*
server
)
FOREIGN_SERVER
*
server
)
{
{
int
error
;
char
*
unset_ptr
=
(
char
*
)
""
;
char
*
unset_ptr
=
(
char
*
)
""
;
DBUG_ENTER
(
"prepare_server_struct"
);
DBUG_ENTER
(
"prepare_server_struct"
);
error
=
0
;
/* these two MUST be set */
/* these two MUST be set */
server
->
server_name
=
strdup_root
(
&
mem
,
server_options
->
server_name
);
server
->
server_name
=
strdup_root
(
&
mem
,
server_options
->
server_name
);
server
->
server_name_length
=
server_options
->
server_name_length
;
server
->
server_name_length
=
server_options
->
server_name_length
;
...
@@ -1083,7 +1077,7 @@ int prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options,
...
@@ -1083,7 +1077,7 @@ int prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options,
server
->
owner
=
server_options
->
owner
?
server
->
owner
=
server_options
->
owner
?
strdup_root
(
&
mem
,
server_options
->
owner
)
:
unset_ptr
;
strdup_root
(
&
mem
,
server_options
->
owner
)
:
unset_ptr
;
DBUG_
RETURN
(
error
)
;
DBUG_
VOID_RETURN
;
}
}
/*
/*
...
@@ -1099,13 +1093,12 @@ int prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options,
...
@@ -1099,13 +1093,12 @@ int prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options,
*/
*/
int
prepare_server_struct_for_update
(
LEX_SERVER_OPTIONS
*
server_options
,
static
void
prepare_server_struct_for_update
(
LEX_SERVER_OPTIONS
*
server_options
,
FOREIGN_SERVER
*
existing
,
FOREIGN_SERVER
*
existing
,
FOREIGN_SERVER
*
altered
)
FOREIGN_SERVER
*
altered
)
{
{
int
error
;
DBUG_ENTER
(
"prepare_server_struct_for_update"
);
DBUG_ENTER
(
"prepare_server_struct_for_update"
);
error
=
0
;
altered
->
server_name
=
strdup_root
(
&
mem
,
server_options
->
server_name
);
altered
->
server_name
=
strdup_root
(
&
mem
,
server_options
->
server_name
);
altered
->
server_name_length
=
server_options
->
server_name_length
;
altered
->
server_name_length
=
server_options
->
server_name_length
;
...
@@ -1156,7 +1149,7 @@ int prepare_server_struct_for_update(LEX_SERVER_OPTIONS *server_options,
...
@@ -1156,7 +1149,7 @@ int prepare_server_struct_for_update(LEX_SERVER_OPTIONS *server_options,
(
strcmp
(
server_options
->
owner
,
existing
->
owner
)))
?
(
strcmp
(
server_options
->
owner
,
existing
->
owner
)))
?
strdup_root
(
&
mem
,
server_options
->
owner
)
:
0
;
strdup_root
(
&
mem
,
server_options
->
owner
)
:
0
;
DBUG_
RETURN
(
error
)
;
DBUG_
VOID_RETURN
;
}
}
/*
/*
...
@@ -1175,16 +1168,65 @@ int prepare_server_struct_for_update(LEX_SERVER_OPTIONS *server_options,
...
@@ -1175,16 +1168,65 @@ int prepare_server_struct_for_update(LEX_SERVER_OPTIONS *server_options,
void
servers_free
(
bool
end
)
void
servers_free
(
bool
end
)
{
{
DBUG_ENTER
(
"servers_free"
);
DBUG_ENTER
(
"servers_free"
);
if
(
!
servers_cache_initialised
)
if
(
!
hash_inited
(
&
servers_cache
)
)
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
VOID
(
pthread_mutex_destroy
(
&
servers_cache_mutex
));
if
(
!
end
)
servers_cache_initialised
=
0
;
{
free_root
(
&
mem
,
MYF
(
MY_MARK_BLOCKS_FREE
));
my_hash_reset
(
&
servers_cache
);
DBUG_VOID_RETURN
;
}
rwlock_destroy
(
&
THR_LOCK_servers
);
free_root
(
&
mem
,
MYF
(
0
));
free_root
(
&
mem
,
MYF
(
0
));
hash_free
(
&
servers_cache
);
hash_free
(
&
servers_cache
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
/*
SYNOPSIS
clone_server(MEM_ROOT *mem_root, FOREIGN_SERVER *orig, FOREIGN_SERVER *buff)
Create a clone of FOREIGN_SERVER. If the supplied mem_root is of
thd->mem_root then the copy is automatically disposed at end of statement.
NOTES
ARGS
MEM_ROOT pointer (strings are copied into this mem root)
FOREIGN_SERVER pointer (made a copy of)
FOREIGN_SERVER buffer (if not-NULL, this pointer is returned)
RETURN VALUE
FOREIGN_SEVER pointer (copy of one supplied FOREIGN_SERVER)
*/
static
FOREIGN_SERVER
*
clone_server
(
MEM_ROOT
*
mem
,
const
FOREIGN_SERVER
*
server
,
FOREIGN_SERVER
*
buffer
)
{
DBUG_ENTER
(
"sql_server.cc:clone_server"
);
if
(
!
buffer
)
buffer
=
(
FOREIGN_SERVER
*
)
alloc_root
(
mem
,
sizeof
(
FOREIGN_SERVER
));
buffer
->
server_name
=
strmake_root
(
mem
,
server
->
server_name
,
server
->
server_name_length
);
buffer
->
port
=
server
->
port
;
buffer
->
server_name_length
=
server
->
server_name_length
;
/* TODO: We need to examine which of these can really be NULL */
buffer
->
db
=
server
->
db
?
strdup_root
(
mem
,
server
->
db
)
:
NULL
;
buffer
->
scheme
=
server
->
scheme
?
strdup_root
(
mem
,
server
->
scheme
)
:
NULL
;
buffer
->
username
=
server
->
username
?
strdup_root
(
mem
,
server
->
username
)
:
NULL
;
buffer
->
password
=
server
->
password
?
strdup_root
(
mem
,
server
->
password
)
:
NULL
;
buffer
->
socket
=
server
->
socket
?
strdup_root
(
mem
,
server
->
socket
)
:
NULL
;
buffer
->
owner
=
server
->
owner
?
strdup_root
(
mem
,
server
->
owner
)
:
NULL
;
buffer
->
host
=
server
->
host
?
strdup_root
(
mem
,
server
->
host
)
:
NULL
;
DBUG_RETURN
(
buffer
);
}
/*
/*
...
@@ -1199,11 +1241,11 @@ void servers_free(bool end)
...
@@ -1199,11 +1241,11 @@ void servers_free(bool end)
*/
*/
FOREIGN_SERVER
*
get_server_by_name
(
const
char
*
server_name
)
FOREIGN_SERVER
*
get_server_by_name
(
MEM_ROOT
*
mem
,
const
char
*
server_name
,
FOREIGN_SERVER
*
buff
)
{
{
ulong
error_num
=
0
;
uint
server_name_length
;
uint
server_name_length
;
FOREIGN_SERVER
*
server
=
0
;
FOREIGN_SERVER
*
server
;
DBUG_ENTER
(
"get_server_by_name"
);
DBUG_ENTER
(
"get_server_by_name"
);
DBUG_PRINT
(
"info"
,
(
"server_name %s"
,
server_name
));
DBUG_PRINT
(
"info"
,
(
"server_name %s"
,
server_name
));
...
@@ -1212,12 +1254,11 @@ FOREIGN_SERVER *get_server_by_name(const char *server_name)
...
@@ -1212,12 +1254,11 @@ FOREIGN_SERVER *get_server_by_name(const char *server_name)
if
(
!
server_name
||
!
strlen
(
server_name
))
if
(
!
server_name
||
!
strlen
(
server_name
))
{
{
DBUG_PRINT
(
"info"
,
(
"server_name not defined!"
));
DBUG_PRINT
(
"info"
,
(
"server_name not defined!"
));
error_num
=
1
;
DBUG_RETURN
((
FOREIGN_SERVER
*
)
NULL
);
DBUG_RETURN
((
FOREIGN_SERVER
*
)
NULL
);
}
}
DBUG_PRINT
(
"info"
,
(
"locking servers_cache"
));
DBUG_PRINT
(
"info"
,
(
"locking servers_cache"
));
VOID
(
pthread_mutex_lock
(
&
servers_cache_mutex
)
);
rw_rdlock
(
&
THR_LOCK_servers
);
if
(
!
(
server
=
(
FOREIGN_SERVER
*
)
hash_search
(
&
servers_cache
,
if
(
!
(
server
=
(
FOREIGN_SERVER
*
)
hash_search
(
&
servers_cache
,
(
byte
*
)
server_name
,
(
byte
*
)
server_name
,
server_name_length
)))
server_name_length
)))
...
@@ -1226,8 +1267,12 @@ FOREIGN_SERVER *get_server_by_name(const char *server_name)
...
@@ -1226,8 +1267,12 @@ FOREIGN_SERVER *get_server_by_name(const char *server_name)
server_name
,
server_name_length
));
server_name
,
server_name_length
));
server
=
(
FOREIGN_SERVER
*
)
NULL
;
server
=
(
FOREIGN_SERVER
*
)
NULL
;
}
}
/* otherwise, make copy of server */
else
server
=
clone_server
(
mem
,
server
,
buff
);
DBUG_PRINT
(
"info"
,
(
"unlocking servers_cache"
));
DBUG_PRINT
(
"info"
,
(
"unlocking servers_cache"
));
VOID
(
pthread_mutex_unlock
(
&
servers_cache_mutex
)
);
rw_unlock
(
&
THR_LOCK_servers
);
DBUG_RETURN
(
server
);
DBUG_RETURN
(
server
);
}
}
sql/sql_servers.h
View file @
8ad2472e
...
@@ -25,40 +25,19 @@ typedef struct st_federated_server
...
@@ -25,40 +25,19 @@ typedef struct st_federated_server
}
FOREIGN_SERVER
;
}
FOREIGN_SERVER
;
/* cache handlers */
/* cache handlers */
my_bool
servers_init
(
bool
dont_read_server_table
);
bool
servers_init
(
bool
dont_read_server_table
);
my_bool
servers_reload
(
THD
*
thd
);
bool
servers_reload
(
THD
*
thd
);
my_bool
get_server_from_table_to_cache
(
TABLE
*
table
);
void
servers_free
(
bool
end
=
0
);
void
servers_free
(
bool
end
=
0
);
/* insert functions */
/* insert functions */
int
create_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
);
int
create_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
);
int
insert_server
(
THD
*
thd
,
FOREIGN_SERVER
*
server_options
);
int
insert_server_record
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
);
int
insert_server_record_into_cache
(
FOREIGN_SERVER
*
server
);
void
store_server_fields_for_insert
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
);
void
store_server_fields_for_insert
(
TABLE
*
table
,
FOREIGN_SERVER
*
existing
,
FOREIGN_SERVER
*
altered
);
int
prepare_server_struct_for_insert
(
LEX_SERVER_OPTIONS
*
server_options
,
FOREIGN_SERVER
*
server
);
/* drop functions */
/* drop functions */
int
drop_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
);
int
drop_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
);
int
delete_server_record
(
TABLE
*
table
,
char
*
server_name
,
int
server_name_length
);
int
delete_server_record_in_cache
(
LEX_SERVER_OPTIONS
*
server_options
);
/* update functions */
/* update functions */
int
alter_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
);
int
alter_server
(
THD
*
thd
,
LEX_SERVER_OPTIONS
*
server_options
);
int
prepare_server_struct_for_update
(
LEX_SERVER_OPTIONS
*
server_options
,
FOREIGN_SERVER
*
existing
,
/* lookup functions */
FOREIGN_SERVER
*
altered
);
FOREIGN_SERVER
*
get_server_by_name
(
MEM_ROOT
*
mem
,
const
char
*
server_name
,
int
update_server
(
THD
*
thd
,
FOREIGN_SERVER
*
existing
,
FOREIGN_SERVER
*
altered
);
FOREIGN_SERVER
*
server_buffer
);
int
update_server_record
(
TABLE
*
table
,
FOREIGN_SERVER
*
server
);
int
update_server_record_in_cache
(
FOREIGN_SERVER
*
existing
,
FOREIGN_SERVER
*
altered
);
/* utility functions */
void
merge_server_struct
(
FOREIGN_SERVER
*
from
,
FOREIGN_SERVER
*
to
);
FOREIGN_SERVER
*
get_server_by_name
(
const
char
*
server_name
);
my_bool
server_exists_in_table
(
THD
*
thd
,
char
*
server_name
);
storage/federated/ha_federated.cc
View file @
8ad2472e
...
@@ -43,23 +43,55 @@
...
@@ -43,23 +43,55 @@
The create table will simply create the .frm file, and within the
The create table will simply create the .frm file, and within the
"CREATE TABLE" SQL, there SHALL be any of the following :
"CREATE TABLE" SQL, there SHALL be any of the following :
comment=scheme://username:password@hostname:port/database/tablename
connection=scheme://username:password@hostname:port/database/tablename
comment=scheme://username@hostname/database/tablename
connection=scheme://username@hostname/database/tablename
comment=scheme://username:password@hostname/database/tablename
connection=scheme://username:password@hostname/database/tablename
comment=scheme://username:password@hostname/database/tablename
connection=scheme://username:password@hostname/database/tablename
- OR -
As of 5.1 (See worklog #3031), federated now allows you to use a non-url
format, taking advantage of mysql.servers:
connection="connection_one"
connection="connection_one/table_foo"
An example would be:
An example would be:
co
mment
=mysql://username:password@hostname:port/database/tablename
co
nnection
=mysql://username:password@hostname:port/database/tablename
***IMPORTANT***
or, if we had:
create server 'server_one' foreign data wrapper 'mysql' options
(HOST '127.0.0.1',
DATABASE 'db1',
USER 'root',
PASSWORD '',
PORT 3306,
SOCKET '',
OWNER 'root');
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(64) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='server_one';
So, this will have been the equivalent of
CONNECTION="mysql://root@127.0.0.1:3306/db1/t1"
This is a first release, conceptual release
Then, we can also change the server to point to a new schema:
Only 'mysql://' is supported at this release.
ALTER SERVER 'server_one' options(DATABASE 'db2');
This comment connection string is necessary for the handler to be
All subsequent calls will now be against db2.t1! Guess what? You don't
able to connect to the foreign server.
have to perform an alter table!
This connecton="connection string" is necessary for the handler to be
able to connect to the foreign server, either by URL, or by server
name.
The basic flow is this:
The basic flow is this:
...
@@ -166,7 +198,7 @@
...
@@ -166,7 +198,7 @@
KEY other_key (other))
KEY other_key (other))
ENGINE="FEDERATED"
ENGINE="FEDERATED"
DEFAULT CHARSET=latin1
DEFAULT CHARSET=latin1
CO
MMENT='
root@127.0.0.1:9306/federated/test_federated';
CO
NNECTION='mysql://
root@127.0.0.1:9306/federated/test_federated';
Notice the "COMMENT" and "ENGINE" field? This is where you
Notice the "COMMENT" and "ENGINE" field? This is where you
respectively set the engine type, "FEDERATED" and foreign
respectively set the engine type, "FEDERATED" and foreign
...
@@ -263,7 +295,7 @@
...
@@ -263,7 +295,7 @@
To run these tests, go into ./mysql-test (based in the directory you
To run these tests, go into ./mysql-test (based in the directory you
built the server in)
built the server in)
./mysql-test-run federated
d
./mysql-test-run federated
To run the test, or if you want to run the test and have debug info:
To run the test, or if you want to run the test and have debug info:
...
@@ -311,7 +343,7 @@
...
@@ -311,7 +343,7 @@
-------------
-------------
These were the files that were modified or created for this
These were the files that were modified or created for this
Federated handler to work:
Federated handler to work
, in 5.0
:
./configure.in
./configure.in
./sql/Makefile.am
./sql/Makefile.am
...
@@ -329,6 +361,13 @@
...
@@ -329,6 +361,13 @@
./sql/ha_federated.cc
./sql/ha_federated.cc
./sql/ha_federated.h
./sql/ha_federated.h
In 5.1
my:~/mysql-build/mysql-5.1-bkbits patg$ ls storage/federated/
CMakeLists.txt Makefile.in ha_federated.h plug.in
Makefile SCCS libfederated.a
Makefile.am ha_federated.cc libfederated_a-ha_federated.o
*/
*/
...
@@ -546,42 +585,39 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num)
...
@@ -546,42 +585,39 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num)
int
buf_len
;
int
buf_len
;
DBUG_ENTER
(
"ha_federated parse_url_error"
);
DBUG_ENTER
(
"ha_federated parse_url_error"
);
if
(
share
->
connection_string
)
{
DBUG_PRINT
(
"info"
,
(
"error: parse_url. Returning error code %d \
freeing share->connection_string %lx"
,
error_num
,
(
long
unsigned
int
)
share
->
connection_string
));
my_free
((
gptr
)
share
->
connection_string
,
MYF
(
0
));
share
->
connection_string
=
0
;
}
buf_len
=
min
(
table
->
s
->
connect_string
.
length
,
buf_len
=
min
(
table
->
s
->
connect_string
.
length
,
FEDERATED_QUERY_BUFFER_SIZE
-
1
);
FEDERATED_QUERY_BUFFER_SIZE
-
1
);
strmake
(
buf
,
table
->
s
->
connect_string
.
str
,
buf_len
);
strmake
(
buf
,
table
->
s
->
connect_string
.
str
,
buf_len
);
my_error
(
error_num
,
MYF
(
0
),
buf
);
my_error
(
error_num
,
MYF
(
0
),
buf
);
DBUG_RETURN
(
error_num
);
DBUG_RETURN
(
error_num
);
}
}
/*
/*
retrieve server object which contains server meta-data
retrieve server object which contains server meta-data
from the system table given a server's name, set share
from the system table given a server's name, set share
connection parameter members
connection parameter members
*/
*/
int
get_connection
(
FEDERATED_SHARE
*
share
)
int
get_connection
(
MEM_ROOT
*
mem_root
,
FEDERATED_SHARE
*
share
)
{
{
int
error_num
=
ER_FOREIGN_SERVER_DOESNT_EXIST
;
int
error_num
=
ER_FOREIGN_SERVER_DOESNT_EXIST
;
char
error_buffer
[
FEDERATED_QUERY_BUFFER_SIZE
];
char
error_buffer
[
FEDERATED_QUERY_BUFFER_SIZE
];
FOREIGN_SERVER
*
server
;
FOREIGN_SERVER
*
server
,
server_buffer
;
DBUG_ENTER
(
"ha_federated::get_connection"
);
DBUG_ENTER
(
"ha_federated::get_connection"
);
/*
get_server_by_name() clones the server if exists and allocates
copies of strings in the supplied mem_root
*/
if
(
!
(
server
=
if
(
!
(
server
=
get_server_by_name
(
share
->
connection_string
)))
get_server_by_name
(
mem_root
,
share
->
connection_string
,
&
server_buffer
)))
{
{
DBUG_PRINT
(
"info"
,
(
"get_server_by_name returned > 0 error condition!"
));
DBUG_PRINT
(
"info"
,
(
"get_server_by_name returned > 0 error condition!"
));
/* need to come up with error handling */
/* need to come up with error handling */
error_num
=
1
;
error_num
=
1
;
goto
error
;
goto
error
;
}
}
DBUG_PRINT
(
"info"
,
(
"get_server_by_name returned server at %lx"
,
(
long
unsigned
int
)
server
));
DBUG_PRINT
(
"info"
,
(
"get_server_by_name returned server at %lx"
,
(
long
unsigned
int
)
server
));
/*
/*
Most of these should never be empty strings, error handling will
Most of these should never be empty strings, error handling will
...
@@ -590,29 +626,22 @@ int get_connection(FEDERATED_SHARE *share)
...
@@ -590,29 +626,22 @@ int get_connection(FEDERATED_SHARE *share)
except there are errors in the trace file of the share being overrun
except there are errors in the trace file of the share being overrun
at the address of the share.
at the address of the share.
*/
*/
if
(
server
->
server_name
)
share
->
server_name_length
=
server
->
server_name_length
;
share
->
server_name
=
server
->
server_name
;
share
->
server_name
=
server
->
server_name
;
share
->
server_name_length
=
server
->
server_name_length
?
server
->
server_name_length
:
0
;
if
(
server
->
username
)
share
->
username
=
server
->
username
;
share
->
username
=
server
->
username
;
if
(
server
->
password
)
share
->
password
=
server
->
password
;
share
->
password
=
server
->
password
;
if
(
server
->
db
)
share
->
database
=
server
->
db
;
share
->
database
=
server
->
db
;
#ifndef I_AM_PARANOID
share
->
port
=
server
->
port
?
(
ushort
)
server
->
port
:
MYSQL_PORT
;
share
->
port
=
server
->
port
>
0
&&
server
->
port
<
65536
?
#else
if
(
server
->
host
)
share
->
port
=
server
->
port
>
1023
&&
server
->
port
<
65536
?
#endif
(
ushort
)
server
->
port
:
MYSQL_PORT
;
share
->
hostname
=
server
->
host
;
share
->
hostname
=
server
->
host
;
if
(
server
->
socket
)
if
(
!
(
share
->
socket
=
server
->
socket
)
&&
share
->
socket
=
server
->
socket
;
!
strcmp
(
share
->
hostname
,
my_localhost
))
else
if
(
strcmp
(
share
->
hostname
,
my_localhost
)
==
0
)
share
->
socket
=
(
char
*
)
MYSQL_UNIX_ADDR
;
share
->
socket
=
my_strdup
(
MYSQL_UNIX_ADDR
,
MYF
(
0
));
if
(
server
->
scheme
)
share
->
scheme
=
server
->
scheme
;
share
->
scheme
=
server
->
scheme
;
else
share
->
scheme
=
NULL
;
DBUG_PRINT
(
"info"
,
(
"share->username %s"
,
share
->
username
));
DBUG_PRINT
(
"info"
,
(
"share->username %s"
,
share
->
username
));
DBUG_PRINT
(
"info"
,
(
"share->password %s"
,
share
->
password
));
DBUG_PRINT
(
"info"
,
(
"share->password %s"
,
share
->
password
));
...
@@ -635,6 +664,7 @@ error:
...
@@ -635,6 +664,7 @@ error:
SYNOPSIS
SYNOPSIS
parse_url()
parse_url()
mem_root MEM_ROOT pointer for memory allocation
share pointer to FEDERATED share
share pointer to FEDERATED share
table pointer to current TABLE class
table pointer to current TABLE class
table_create_flag determines what error to throw
table_create_flag determines what error to throw
...
@@ -684,7 +714,7 @@ error:
...
@@ -684,7 +714,7 @@ error:
*/
*/
static
int
parse_url
(
FEDERATED_SHARE
*
share
,
TABLE
*
table
,
static
int
parse_url
(
MEM_ROOT
*
mem_root
,
FEDERATED_SHARE
*
share
,
TABLE
*
table
,
uint
table_create_flag
)
uint
table_create_flag
)
{
{
uint
error_num
=
(
table_create_flag
?
uint
error_num
=
(
table_create_flag
?
...
@@ -698,20 +728,19 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
...
@@ -698,20 +728,19 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
DBUG_PRINT
(
"info"
,
(
"Length: %d"
,
table
->
s
->
connect_string
.
length
));
DBUG_PRINT
(
"info"
,
(
"Length: %d"
,
table
->
s
->
connect_string
.
length
));
DBUG_PRINT
(
"info"
,
(
"String: '%.*s'"
,
table
->
s
->
connect_string
.
length
,
DBUG_PRINT
(
"info"
,
(
"String: '%.*s'"
,
table
->
s
->
connect_string
.
length
,
table
->
s
->
connect_string
.
str
));
table
->
s
->
connect_string
.
str
));
share
->
connection_string
=
my_strndup
(
table
->
s
->
connect_string
.
str
,
share
->
connection_string
=
strmake_root
(
mem_root
,
table
->
s
->
connect_string
.
str
,
table
->
s
->
connect_string
.
length
,
table
->
s
->
connect_string
.
length
);
MYF
(
0
));
// Add a null for later termination of table name
share
->
connection_string
[
table
->
s
->
connect_string
.
length
]
=
0
;
DBUG_PRINT
(
"info"
,(
"parse_url alloced share->connection_string %lx"
,
DBUG_PRINT
(
"info"
,(
"parse_url alloced share->connection_string %lx"
,
(
long
unsigned
int
)
share
->
connection_string
));
(
long
unsigned
int
)
share
->
connection_string
));
DBUG_PRINT
(
"info"
,(
"share->connection_string %s"
,
share
->
connection_string
));
DBUG_PRINT
(
"info"
,(
"share->connection_string %s"
,
share
->
connection_string
));
/* No delimiters, must be a straight connection name */
/*
if
(
(
!
strchr
(
share
->
connection_string
,
'/'
))
&&
No :// or @ in connection string. Must be a straight connection name of
(
!
strchr
(
share
->
connection_string
,
'@'
))
&&
either "servername" or "servername/tablename"
(
!
strchr
(
share
->
connection_string
,
';'
)))
*/
if
(
(
!
strstr
(
share
->
connection_string
,
"://"
)
&&
(
!
strchr
(
share
->
connection_string
,
'@'
))))
{
{
DBUG_PRINT
(
"info"
,
DBUG_PRINT
(
"info"
,
...
@@ -720,17 +749,51 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
...
@@ -720,17 +749,51 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
share
->
connection_string
,
share
->
connection_string
,
(
long
unsigned
int
)
share
->
connection_string
));
(
long
unsigned
int
)
share
->
connection_string
));
/* ok, so we do a little parsing, but not completely! */
share
->
parsed
=
FALSE
;
share
->
parsed
=
FALSE
;
if
((
error_num
=
get_connection
(
share
)))
/*
If there is a single '/' in the connection string, this means the user is
specifying a table name
*/
if
((
share
->
table_name
=
strchr
(
share
->
connection_string
,
'/'
)))
{
share
->
connection_string
[
share
->
table_name
-
share
->
connection_string
]
=
'\0'
;
share
->
table_name
++
;
share
->
table_name_length
=
strlen
(
share
->
table_name
);
DBUG_PRINT
(
"info"
,
(
"internal format, parsed table_name share->connection_string \
%s share->table_name %s"
,
share
->
connection_string
,
share
->
table_name
));
/*
there better not be any more '/'s !
*/
if
(
strchr
(
share
->
table_name
,
'/'
))
goto
error
;
goto
error
;
}
/*
otherwise, straight server name, use tablename of federated table
as remote table name
*/
else
{
/*
/*
connection specifies everything but, resort to
connection specifies everything but, resort to
expecting remote and foreign table names to match
expecting remote and foreign table names to match
*/
*/
share
->
table_name
=
table
->
s
->
table_name
.
str
;
share
->
table_name
=
strmake_root
(
mem_root
,
table
->
s
->
table_name
.
str
,
share
->
table_name_length
=
table
->
s
->
table_name
.
length
;
(
share
->
table_name_length
=
table
->
s
->
table_name
.
length
));
share
->
table_name
[
share
->
table_name_length
]
=
'\0'
;
DBUG_PRINT
(
"info"
,
(
"internal format, default table_name share->connection_string \
%s share->table_name %s"
,
share
->
connection_string
,
share
->
table_name
));
}
if
((
error_num
=
get_connection
(
mem_root
,
share
)))
goto
error
;
}
}
else
else
{
{
...
@@ -816,7 +879,7 @@ Then password is a null string, so set to NULL
...
@@ -816,7 +879,7 @@ Then password is a null string, so set to NULL
if
(
!
share
->
port
)
if
(
!
share
->
port
)
{
{
if
(
strcmp
(
share
->
hostname
,
my_localhost
)
==
0
)
if
(
strcmp
(
share
->
hostname
,
my_localhost
)
==
0
)
share
->
socket
=
my_strdup
(
MYSQL_UNIX_ADDR
,
MYF
(
0
))
;
share
->
socket
=
(
char
*
)
MYSQL_UNIX_ADDR
;
else
else
share
->
port
=
MYSQL_PORT
;
share
->
port
=
MYSQL_PORT
;
}
}
...
@@ -1420,22 +1483,26 @@ err:
...
@@ -1420,22 +1483,26 @@ err:
static
FEDERATED_SHARE
*
get_share
(
const
char
*
table_name
,
TABLE
*
table
)
static
FEDERATED_SHARE
*
get_share
(
const
char
*
table_name
,
TABLE
*
table
)
{
{
char
*
select_query
;
char
query_buffer
[
FEDERATED_QUERY_BUFFER_SIZE
];
char
query_buffer
[
FEDERATED_QUERY_BUFFER_SIZE
];
Field
**
field
;
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
=
NULL
,
tmp_share
;
FEDERATED_SHARE
*
share
=
NULL
,
tmp_share
;
MEM_ROOT
mem_root
;
DBUG_ENTER
(
"ha_federated.cc::get_share"
);
/*
/*
In order to use this string, we must first zero it's length,
In order to use this string, we must first zero it's length,
or it will contain garbage
or it will contain garbage
*/
*/
query
.
length
(
0
);
query
.
length
(
0
);
init_alloc_root
(
&
mem_root
,
256
,
0
);
pthread_mutex_lock
(
&
federated_mutex
);
pthread_mutex_lock
(
&
federated_mutex
);
tmp_share
.
share_key
=
table_name
;
tmp_share
.
share_key
=
table_name
;
tmp_share
.
share_key_length
=
strlen
(
table_name
);
tmp_share
.
share_key_length
=
strlen
(
table_name
);
if
(
parse_url
(
&
tmp_share
,
table
,
0
))
if
(
parse_url
(
&
mem_root
,
&
tmp_share
,
table
,
0
))
goto
error
;
goto
error
;
/* TODO: change tmp_share.scheme to LEX_STRING object */
/* TODO: change tmp_share.scheme to LEX_STRING object */
...
@@ -1456,24 +1523,17 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
...
@@ -1456,24 +1523,17 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
query
.
length
(
query
.
length
()
-
sizeof_trailing_comma
);
query
.
length
(
query
.
length
()
-
sizeof_trailing_comma
);
query
.
append
(
STRING_WITH_LEN
(
" FROM `"
));
query
.
append
(
STRING_WITH_LEN
(
" FROM `"
));
query
.
append
(
tmp_share
.
table_name
,
tmp_share
.
table_name_length
);
query
.
append
(
STRING_WITH_LEN
(
"`"
));
DBUG_PRINT
(
"info"
,
(
"calling alloc_root"
));
if
(
!
(
share
=
(
FEDERATED_SHARE
*
)
if
(
!
(
share
=
(
FEDERATED_SHARE
*
)
memdup_root
(
&
mem_root
,
(
char
*
)
&
tmp_share
,
sizeof
(
*
share
)))
||
my_multi_malloc
(
MYF
(
MY_WME
),
!
(
share
->
select_query
=
(
char
*
)
strmake_root
(
&
mem_root
,
query
.
ptr
(),
query
.
length
())))
&
share
,
sizeof
(
*
share
),
&
select_query
,
query
.
length
()
+
table
->
s
->
connect_string
.
length
+
1
,
NullS
)))
goto
error
;
goto
error
;
memcpy
(
share
,
&
tmp_share
,
sizeof
(
tmp_share
));
share
->
table_name_length
=
strlen
(
share
->
table_name
);
/* TODO: share->table_name to LEX_STRING object */
query
.
append
(
share
->
table_name
,
share
->
table_name_length
);
query
.
append
(
STRING_WITH_LEN
(
"`"
));
share
->
select_query
=
select_query
;
strmov
(
share
->
select_query
,
query
.
ptr
());
share
->
use_count
=
0
;
share
->
use_count
=
0
;
share
->
mem_root
=
mem_root
;
DBUG_PRINT
(
"info"
,
DBUG_PRINT
(
"info"
,
(
"share->select_query %s"
,
share
->
select_query
));
(
"share->select_query %s"
,
share
->
select_query
));
...
@@ -1482,17 +1542,18 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
...
@@ -1482,17 +1542,18 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
thr_lock_init
(
&
share
->
lock
);
thr_lock_init
(
&
share
->
lock
);
pthread_mutex_init
(
&
share
->
mutex
,
MY_MUTEX_INIT_FAST
);
pthread_mutex_init
(
&
share
->
mutex
,
MY_MUTEX_INIT_FAST
);
}
}
else
free_root
(
&
mem_root
,
MYF
(
0
));
/* prevents memory leak */
share
->
use_count
++
;
share
->
use_count
++
;
pthread_mutex_unlock
(
&
federated_mutex
);
pthread_mutex_unlock
(
&
federated_mutex
);
return
share
;
DBUG_RETURN
(
share
)
;
error:
error:
pthread_mutex_unlock
(
&
federated_mutex
);
pthread_mutex_unlock
(
&
federated_mutex
);
my_free
((
gptr
)
tmp_share
.
connection_string
,
MYF
(
MY_ALLOW_ZERO_PTR
));
free_root
(
&
mem_root
,
MYF
(
0
));
tmp_share
.
connection_string
=
0
;
DBUG_RETURN
(
NULL
);
my_free
((
gptr
)
share
,
MYF
(
MY_ALLOW_ZERO_PTR
));
return
NULL
;
}
}
...
@@ -1504,23 +1565,16 @@ error:
...
@@ -1504,23 +1565,16 @@ error:
static
int
free_share
(
FEDERATED_SHARE
*
share
)
static
int
free_share
(
FEDERATED_SHARE
*
share
)
{
{
MEM_ROOT
mem_root
=
share
->
mem_root
;
DBUG_ENTER
(
"free_share"
);
DBUG_ENTER
(
"free_share"
);
pthread_mutex_lock
(
&
federated_mutex
);
pthread_mutex_lock
(
&
federated_mutex
);
if
(
!--
share
->
use_count
)
if
(
!--
share
->
use_count
)
{
{
hash_delete
(
&
federated_open_tables
,
(
byte
*
)
share
);
hash_delete
(
&
federated_open_tables
,
(
byte
*
)
share
);
if
(
share
->
parsed
)
my_free
((
gptr
)
share
->
socket
,
MYF
(
MY_ALLOW_ZERO_PTR
));
/*if (share->connection_string)
{
*/
my_free
((
gptr
)
share
->
connection_string
,
MYF
(
MY_ALLOW_ZERO_PTR
));
share
->
connection_string
=
0
;
/*}*/
thr_lock_delete
(
&
share
->
lock
);
thr_lock_delete
(
&
share
->
lock
);
VOID
(
pthread_mutex_destroy
(
&
share
->
mutex
));
VOID
(
pthread_mutex_destroy
(
&
share
->
mutex
));
my_free
((
gptr
)
share
,
MYF
(
0
));
free_root
(
&
mem_root
,
MYF
(
0
));
}
}
pthread_mutex_unlock
(
&
federated_mutex
);
pthread_mutex_unlock
(
&
federated_mutex
);
...
@@ -1589,6 +1643,8 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
...
@@ -1589,6 +1643,8 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
mysql_options
(
mysql
,
MYSQL_SET_CHARSET_NAME
,
mysql_options
(
mysql
,
MYSQL_SET_CHARSET_NAME
,
this
->
table
->
s
->
table_charset
->
csname
);
this
->
table
->
s
->
table_charset
->
csname
);
DBUG_PRINT
(
"info"
,
(
"calling mysql_real_connect hostname %s user %s"
,
share
->
hostname
,
share
->
username
));
if
(
!
mysql
||
!
mysql_real_connect
(
mysql
,
if
(
!
mysql
||
!
mysql_real_connect
(
mysql
,
share
->
hostname
,
share
->
hostname
,
share
->
username
,
share
->
username
,
...
@@ -2831,15 +2887,13 @@ int ha_federated::create(const char *name, TABLE *table_arg,
...
@@ -2831,15 +2887,13 @@ int ha_federated::create(const char *name, TABLE *table_arg,
HA_CREATE_INFO
*
create_info
)
HA_CREATE_INFO
*
create_info
)
{
{
int
retval
;
int
retval
;
THD
*
thd
=
current_thd
;
FEDERATED_SHARE
tmp_share
;
// Only a temporary share, to test the url
FEDERATED_SHARE
tmp_share
;
// Only a temporary share, to test the url
DBUG_ENTER
(
"ha_federated::create"
);
DBUG_ENTER
(
"ha_federated::create"
);
if
(
!
(
retval
=
parse_url
(
&
tmp_share
,
table_arg
,
1
)))
if
(
!
(
retval
=
parse_url
(
thd
->
mem_root
,
&
tmp_share
,
table_arg
,
1
)))
retval
=
check_foreign_data_source
(
&
tmp_share
,
1
);
retval
=
check_foreign_data_source
(
&
tmp_share
,
1
);
/* free this because strdup created it in parse_url */
my_free
((
gptr
)
tmp_share
.
connection_string
,
MYF
(
MY_ALLOW_ZERO_PTR
));
tmp_share
.
connection_string
=
0
;
DBUG_RETURN
(
retval
);
DBUG_RETURN
(
retval
);
}
}
...
...
storage/federated/ha_federated.h
View file @
8ad2472e
...
@@ -43,6 +43,8 @@
...
@@ -43,6 +43,8 @@
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
{
MEM_ROOT
mem_root
;
bool
parsed
;
bool
parsed
;
/* this key is unique db/tablename */
/* this key is unique db/tablename */
const
char
*
share_key
;
const
char
*
share_key
;
...
@@ -67,6 +69,7 @@ typedef struct st_federated_share {
...
@@ -67,6 +69,7 @@ typedef struct st_federated_share {
char
*
sport
;
char
*
sport
;
int
share_key_length
;
int
share_key_length
;
ushort
port
;
ushort
port
;
uint
table_name_length
,
server_name_length
,
connect_string_length
,
use_count
;
uint
table_name_length
,
server_name_length
,
connect_string_length
,
use_count
;
pthread_mutex_t
mutex
;
pthread_mutex_t
mutex
;
THR_LOCK
lock
;
THR_LOCK
lock
;
...
...
storage/heap/ha_heap.cc
View file @
8ad2472e
...
@@ -628,6 +628,9 @@ int ha_heap::create(const char *name, TABLE *table_arg,
...
@@ -628,6 +628,9 @@ int ha_heap::create(const char *name, TABLE *table_arg,
seg
->
length
=
(
uint
)
key_part
->
length
;
seg
->
length
=
(
uint
)
key_part
->
length
;
seg
->
flag
=
key_part
->
key_part_flag
;
seg
->
flag
=
key_part
->
key_part_flag
;
if
(
field
->
flags
&
(
ENUM_FLAG
|
SET_FLAG
))
seg
->
charset
=
&
my_charset_bin
;
else
seg
->
charset
=
field
->
charset
();
seg
->
charset
=
field
->
charset
();
if
(
field
->
null_ptr
)
if
(
field
->
null_ptr
)
{
{
...
...
storage/heap/hp_write.c
View file @
8ad2472e
...
@@ -105,7 +105,6 @@ int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *record,
...
@@ -105,7 +105,6 @@ int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *record,
heap_rb_param
custom_arg
;
heap_rb_param
custom_arg
;
uint
old_allocated
;
uint
old_allocated
;
info
->
last_pos
=
NULL
;
/* For heap_rnext/heap_rprev */
custom_arg
.
keyseg
=
keyinfo
->
seg
;
custom_arg
.
keyseg
=
keyinfo
->
seg
;
custom_arg
.
key_length
=
hp_rb_make_key
(
keyinfo
,
info
->
recbuf
,
record
,
recpos
);
custom_arg
.
key_length
=
hp_rb_make_key
(
keyinfo
,
info
->
recbuf
,
record
,
recpos
);
if
(
keyinfo
->
flag
&
HA_NOSAME
)
if
(
keyinfo
->
flag
&
HA_NOSAME
)
...
...
storage/myisam/ha_myisam.cc
View file @
8ad2472e
...
@@ -635,6 +635,9 @@ bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
...
@@ -635,6 +635,9 @@ bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
int
ha_myisam
::
open
(
const
char
*
name
,
int
mode
,
uint
test_if_locked
)
int
ha_myisam
::
open
(
const
char
*
name
,
int
mode
,
uint
test_if_locked
)
{
{
MI_KEYDEF
*
keyinfo
;
MI_COLUMNDEF
*
recinfo
=
0
;
uint
recs
;
uint
i
;
uint
i
;
/*
/*
...
@@ -657,6 +660,26 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
...
@@ -657,6 +660,26 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
if
(
!
(
file
=
mi_open
(
name
,
mode
,
test_if_locked
|
HA_OPEN_FROM_SQL_LAYER
)))
if
(
!
(
file
=
mi_open
(
name
,
mode
,
test_if_locked
|
HA_OPEN_FROM_SQL_LAYER
)))
return
(
my_errno
?
my_errno
:
-
1
);
return
(
my_errno
?
my_errno
:
-
1
);
if
(
!
table
->
s
->
tmp_table
)
/* No need to perform a check for tmp table */
{
if
((
my_errno
=
table2myisam
(
table
,
&
keyinfo
,
&
recinfo
,
&
recs
)))
{
/* purecov: begin inspected */
DBUG_PRINT
(
"error"
,
(
"Failed to convert TABLE object to MyISAM "
"key and column definition"
));
goto
err
;
/* purecov: end */
}
if
(
check_definition
(
keyinfo
,
recinfo
,
table
->
s
->
keys
,
recs
,
file
->
s
->
keyinfo
,
file
->
s
->
rec
,
file
->
s
->
base
.
keys
,
file
->
s
->
base
.
fields
,
true
))
{
/* purecov: begin inspected */
my_errno
=
HA_ERR_CRASHED
;
goto
err
;
/* purecov: end */
}
}
if
(
test_if_locked
&
(
HA_OPEN_IGNORE_IF_LOCKED
|
HA_OPEN_TMP_TABLE
))
if
(
test_if_locked
&
(
HA_OPEN_IGNORE_IF_LOCKED
|
HA_OPEN_TMP_TABLE
))
VOID
(
mi_extra
(
file
,
HA_EXTRA_NO_WAIT_LOCK
,
0
));
VOID
(
mi_extra
(
file
,
HA_EXTRA_NO_WAIT_LOCK
,
0
));
...
@@ -677,7 +700,18 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
...
@@ -677,7 +700,18 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
(
struct
st_mysql_ftparser
*
)
parser
->
plugin
->
info
;
(
struct
st_mysql_ftparser
*
)
parser
->
plugin
->
info
;
table
->
key_info
[
i
].
block_size
=
file
->
s
->
keyinfo
[
i
].
block_length
;
table
->
key_info
[
i
].
block_size
=
file
->
s
->
keyinfo
[
i
].
block_length
;
}
}
return
(
0
);
my_errno
=
0
;
goto
end
;
err:
this
->
close
();
end:
/*
Both recinfo and keydef are allocated by my_multi_malloc(), thus only
recinfo must be freed.
*/
if
(
recinfo
)
my_free
((
gptr
)
recinfo
,
MYF
(
0
));
return
my_errno
;
}
}
int
ha_myisam
::
close
(
void
)
int
ha_myisam
::
close
(
void
)
...
@@ -1023,6 +1057,22 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize)
...
@@ -1023,6 +1057,22 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize)
ha_rows
rows
=
file
->
state
->
records
;
ha_rows
rows
=
file
->
state
->
records
;
DBUG_ENTER
(
"ha_myisam::repair"
);
DBUG_ENTER
(
"ha_myisam::repair"
);
/*
Normally this method is entered with a properly opened table. If the
repair fails, it can be repeated with more elaborate options. Under
special circumstances it can happen that a repair fails so that it
closed the data file and cannot re-open it. In this case file->dfile
is set to -1. We must not try another repair without an open data
file. (Bug #25289)
*/
if
(
file
->
dfile
==
-
1
)
{
sql_print_information
(
"Retrying repair of: '%s' failed. "
"Please try REPAIR EXTENDED or myisamchk"
,
table
->
s
->
path
.
str
);
DBUG_RETURN
(
HA_ADMIN_FAILED
);
}
param
.
db_name
=
table
->
s
->
db
.
str
;
param
.
db_name
=
table
->
s
->
db
.
str
;
param
.
table_name
=
table
->
alias
;
param
.
table_name
=
table
->
alias
;
param
.
tmpfile_createflag
=
O_RDWR
|
O_TRUNC
;
param
.
tmpfile_createflag
=
O_RDWR
|
O_TRUNC
;
...
...
storage/myisam/mi_create.c
View file @
8ad2472e
...
@@ -573,6 +573,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
...
@@ -573,6 +573,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
pthread_mutex_lock
(
&
THR_LOCK_myisam
);
pthread_mutex_lock
(
&
THR_LOCK_myisam
);
/*
NOTE: For test_if_reopen() we need a real path name. Hence we need
MY_RETURN_REAL_PATH for every fn_format(filename, ...).
*/
if
(
ci
->
index_file_name
)
if
(
ci
->
index_file_name
)
{
{
char
*
iext
=
strrchr
(
ci
->
index_file_name
,
'.'
);
char
*
iext
=
strrchr
(
ci
->
index_file_name
,
'.'
);
...
@@ -584,13 +588,14 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
...
@@ -584,13 +588,14 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if
((
path
=
strrchr
(
ci
->
index_file_name
,
FN_LIBCHAR
)))
if
((
path
=
strrchr
(
ci
->
index_file_name
,
FN_LIBCHAR
)))
*
path
=
'\0'
;
*
path
=
'\0'
;
fn_format
(
filename
,
name
,
ci
->
index_file_name
,
MI_NAME_IEXT
,
fn_format
(
filename
,
name
,
ci
->
index_file_name
,
MI_NAME_IEXT
,
MY_REPLACE_DIR
|
MY_UNPACK_FILENAME
|
MY_APPEND_EXT
);
MY_REPLACE_DIR
|
MY_UNPACK_FILENAME
|
MY_RETURN_REAL_PATH
|
MY_APPEND_EXT
);
}
}
else
else
{
{
fn_format
(
filename
,
ci
->
index_file_name
,
""
,
MI_NAME_IEXT
,
fn_format
(
filename
,
ci
->
index_file_name
,
""
,
MI_NAME_IEXT
,
MY_UNPACK_FILENAME
|
(
have_iext
?
MY_REPLACE_EXT
:
MY_UNPACK_FILENAME
|
MY_RETURN_REAL_PATH
|
MY_APPEND_EXT
));
(
have_iext
?
MY_REPLACE_EXT
:
MY_APPEND_EXT
));
}
}
fn_format
(
linkname
,
name
,
""
,
MI_NAME_IEXT
,
fn_format
(
linkname
,
name
,
""
,
MI_NAME_IEXT
,
MY_UNPACK_FILENAME
|
MY_APPEND_EXT
);
MY_UNPACK_FILENAME
|
MY_APPEND_EXT
);
...
@@ -603,10 +608,11 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
...
@@ -603,10 +608,11 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
}
}
else
else
{
{
char
*
iext
=
strrchr
(
name
,
'.'
);
int
have_iext
=
iext
&&
!
strcmp
(
iext
,
MI_NAME_IEXT
);
fn_format
(
filename
,
name
,
""
,
MI_NAME_IEXT
,
fn_format
(
filename
,
name
,
""
,
MI_NAME_IEXT
,
(
MY_UNPACK_FILENAME
|
MY_UNPACK_FILENAME
|
MY_RETURN_REAL_PATH
|
(
flags
&
HA_DONT_TOUCH_DATA
)
?
MY_RETURN_REAL_PATH
:
0
)
|
(
have_iext
?
MY_REPLACE_EXT
:
MY_APPEND_EXT
));
MY_APPEND_EXT
);
linkname_ptr
=
0
;
linkname_ptr
=
0
;
/* Replace the current file */
/* Replace the current file */
create_flag
=
MY_DELETE_OLD
;
create_flag
=
MY_DELETE_OLD
;
...
@@ -618,6 +624,9 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
...
@@ -618,6 +624,9 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
A TRUNCATE command checks for the table in the cache only and could
A TRUNCATE command checks for the table in the cache only and could
be fooled to believe, the table is not open.
be fooled to believe, the table is not open.
Pull the emergency brake in this situation. (Bug #8306)
Pull the emergency brake in this situation. (Bug #8306)
NOTE: The filename is compared against unique_file_name of every
open table. Hence we need a real path here.
*/
*/
if
(
test_if_reopen
(
filename
))
if
(
test_if_reopen
(
filename
))
{
{
...
...
storage/myisam/mi_range.c
View file @
8ad2472e
...
@@ -138,8 +138,42 @@ static ha_rows _mi_record_pos(MI_INFO *info, const byte *key,
...
@@ -138,8 +138,42 @@ static ha_rows _mi_record_pos(MI_INFO *info, const byte *key,
if
(
!
(
nextflag
&
(
SEARCH_FIND
|
SEARCH_NO_FIND
|
SEARCH_LAST
)))
if
(
!
(
nextflag
&
(
SEARCH_FIND
|
SEARCH_NO_FIND
|
SEARCH_LAST
)))
key_len
=
USE_WHOLE_KEY
;
key_len
=
USE_WHOLE_KEY
;
/*
my_handler.c:mi_compare_text() has a flag 'skip_end_space'.
This is set in my_handler.c:ha_key_cmp() in dependence on the
compare flags 'nextflag' and the column type.
TEXT columns are of type HA_KEYTYPE_VARTEXT. In this case the
condition is skip_end_space= ((nextflag & (SEARCH_FIND |
SEARCH_UPDATE)) == SEARCH_FIND).
SEARCH_FIND is used for an exact key search. The combination
SEARCH_FIND | SEARCH_UPDATE is used in write/update/delete
operations with a comment like "Not real duplicates", whatever this
means. From the condition above we can see that 'skip_end_space' is
always false for these operations. The result is that trailing space
counts in key comparison and hence, emtpy strings ('', string length
zero, but not NULL) compare less that strings starting with control
characters and these in turn compare less than strings starting with
blanks.
When estimating the number of records in a key range, we request an
exact search for the minimum key. This translates into a plain
SEARCH_FIND flag. Using this alone would lead to a 'skip_end_space'
compare. Empty strings would be expected above control characters.
Their keys would not be found because they are located below control
characters.
This is the reason that we add the SEARCH_UPDATE flag here. It makes
the key estimation compare in the same way like key write operations
do. Olny so we will find the keys where they have been inserted.
Adding the flag unconditionally does not hurt as it is used in the
above mentioned condition only. So it can safely be used together
with other flags.
*/
pos
=
_mi_search_pos
(
info
,
keyinfo
,
key_buff
,
key_len
,
pos
=
_mi_search_pos
(
info
,
keyinfo
,
key_buff
,
key_len
,
nextflag
|
SEARCH_SAVE_BUFF
,
nextflag
|
SEARCH_SAVE_BUFF
|
SEARCH_UPDATE
,
info
->
s
->
state
.
key_root
[
inx
]);
info
->
s
->
state
.
key_root
[
inx
]);
if
(
pos
>=
0
.
0
)
if
(
pos
>=
0
.
0
)
{
{
...
...
storage/myisam/mi_search.c
View file @
8ad2472e
...
@@ -926,11 +926,16 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
...
@@ -926,11 +926,16 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
/*
/*
Keys are compressed the following way:
Keys are compressed the following way:
prefix length Packed length of prefix
for the prev key.
(1 or 3 bytes)
prefix length Packed length of prefix
common with prev key
(1 or 3 bytes)
for each key segment:
for each key segment:
[is null] Null indicator if can be null (1 byte, zero means null)
[is null] Null indicator if can be null (1 byte, zero means null)
[length] Packed length if varlength (1 or 3 bytes)
[length] Packed length if varlength (1 or 3 bytes)
key segment 'length' bytes of key segment value
pointer Reference to the data file (last_keyseg->length).
pointer Reference to the data file (last_keyseg->length).
get_key_length() is a macro. It gets the prefix length from 'page'
and puts it into 'length'. It increments 'page' by 1 or 3, depending
on the packed length of the prefix length.
*/
*/
get_key_length
(
length
,
page
);
get_key_length
(
length
,
page
);
if
(
length
)
if
(
length
)
...
@@ -945,34 +950,44 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
...
@@ -945,34 +950,44 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
my_errno
=
HA_ERR_CRASHED
;
my_errno
=
HA_ERR_CRASHED
;
DBUG_RETURN
(
0
);
/* Wrong key */
DBUG_RETURN
(
0
);
/* Wrong key */
}
}
from
=
key
;
from_end
=
key
+
length
;
/* Key is packed against prev key, take prefix from prev key. */
from
=
key
;
from_end
=
key
+
length
;
}
}
else
else
{
{
from
=
page
;
from_end
=
page_end
;
/* Not packed key */
/* Key is not packed against prev key, take all from page buffer. */
from
=
page
;
from_end
=
page_end
;
}
}
/*
/*
The trouble is that key is split in two parts:
The trouble is that key can be split in two parts:
The first part is in from ...from_end-1.
The first part (prefix) is in from .. from_end - 1.
The second part starts at page
The second part starts at page.
The split can be at every byte position. So we need to check for
the end of the first part before using every byte.
*/
*/
for
(
keyseg
=
keyinfo
->
seg
;
keyseg
->
type
;
keyseg
++
)
for
(
keyseg
=
keyinfo
->
seg
;
keyseg
->
type
;
keyseg
++
)
{
{
if
(
keyseg
->
flag
&
HA_NULL_PART
)
if
(
keyseg
->
flag
&
HA_NULL_PART
)
{
{
/* If prefix is used up, switch to rest. */
if
(
from
==
from_end
)
{
from
=
page
;
from_end
=
page_end
;
}
if
(
from
==
from_end
)
{
from
=
page
;
from_end
=
page_end
;
}
if
(
!
(
*
key
++
=
*
from
++
))
if
(
!
(
*
key
++
=
*
from
++
))
continue
;
/* Null part */
continue
;
/* Null part */
}
}
if
(
keyseg
->
flag
&
(
HA_VAR_LENGTH_PART
|
HA_BLOB_PART
|
HA_SPACE_PACK
))
if
(
keyseg
->
flag
&
(
HA_VAR_LENGTH_PART
|
HA_BLOB_PART
|
HA_SPACE_PACK
))
{
{
/*
Get length of dynamic length key part
*/
/*
If prefix is used up, switch to rest.
*/
if
(
from
==
from_end
)
{
from
=
page
;
from_end
=
page_end
;
}
if
(
from
==
from_end
)
{
from
=
page
;
from_end
=
page_end
;
}
/* Get length of dynamic length key part */
if
((
length
=
(
*
key
++
=
*
from
++
))
==
255
)
if
((
length
=
(
*
key
++
=
*
from
++
))
==
255
)
{
{
/* If prefix is used up, switch to rest. */
if
(
from
==
from_end
)
{
from
=
page
;
from_end
=
page_end
;
}
if
(
from
==
from_end
)
{
from
=
page
;
from_end
=
page_end
;
}
length
=
(
uint
)
((
*
key
++
=
*
from
++
))
<<
8
;
length
=
(
uint
)
((
*
key
++
=
*
from
++
))
<<
8
;
/* If prefix is used up, switch to rest. */
if
(
from
==
from_end
)
{
from
=
page
;
from_end
=
page_end
;
}
if
(
from
==
from_end
)
{
from
=
page
;
from_end
=
page_end
;
}
length
+=
(
uint
)
((
*
key
++
=
*
from
++
));
length
+=
(
uint
)
((
*
key
++
=
*
from
++
));
}
}
...
@@ -992,14 +1007,26 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
...
@@ -992,14 +1007,26 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
key
+=
length
;
key
+=
length
;
from
+=
length
;
from
+=
length
;
}
}
/*
Last segment (type == 0) contains length of data pointer.
If we have mixed key blocks with data pointer and key block pointer,
we have to copy both.
*/
length
=
keyseg
->
length
+
nod_flag
;
length
=
keyseg
->
length
+
nod_flag
;
if
((
tmp
=
(
uint
)
(
from_end
-
from
))
<=
length
)
if
((
tmp
=
(
uint
)
(
from_end
-
from
))
<=
length
)
{
{
/* Remaining length is less or equal max possible length. */
memcpy
(
key
+
tmp
,
page
,
length
-
tmp
);
/* Get last part of key */
memcpy
(
key
+
tmp
,
page
,
length
-
tmp
);
/* Get last part of key */
*
page_pos
=
page
+
length
-
tmp
;
*
page_pos
=
page
+
length
-
tmp
;
}
}
else
else
{
{
/*
Remaining length is greater than max possible length.
This can happen only if we switched to the new key bytes already.
'page_end' is calculated with MI_MAX_KEY_BUFF. So it can be far
behind the real end of the key.
*/
if
(
from_end
!=
page_end
)
if
(
from_end
!=
page_end
)
{
{
DBUG_PRINT
(
"error"
,(
"Error when unpacking key"
));
DBUG_PRINT
(
"error"
,(
"Error when unpacking key"
));
...
@@ -1007,6 +1034,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
...
@@ -1007,6 +1034,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
my_errno
=
HA_ERR_CRASHED
;
my_errno
=
HA_ERR_CRASHED
;
DBUG_RETURN
(
0
);
/* Error */
DBUG_RETURN
(
0
);
/* Error */
}
}
/* Copy data pointer and, if appropriate, key block pointer. */
memcpy
((
byte
*
)
key
,(
byte
*
)
from
,(
size_t
)
length
);
memcpy
((
byte
*
)
key
,(
byte
*
)
from
,(
size_t
)
length
);
*
page_pos
=
from
+
length
;
*
page_pos
=
from
+
length
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment