mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Added federatedx storage engine
Fixed compiler warnings client/mysqladmin.cc: Fixed compiler warning extra/yassl/taocrypt/src/twofish.cpp: Fixed compiler warning libmysqld/Makefile.am: Use federatedx instead of federated (Should actually be removed) mysql-test/mysql-test-run.pl: Fixed warning mysql-test/valgrind.supp: Removed warning found on 64 bit Linux machine storage/pbxt/src/cache_xt.cc: Fixed compile warning storage/xtradb/include/buf0buf.ic: Fixed compiler warning
This commit is contained in:
@ -1043,7 +1043,7 @@ static int drop_db(MYSQL *mysql, const char *db)
|
|||||||
printf("Do you really want to drop the '%s' database [y/N] ",db);
|
printf("Do you really want to drop the '%s' database [y/N] ",db);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
if (fgets(buf,sizeof(buf)-1,stdin) == 0 ||
|
if (fgets(buf,sizeof(buf)-1,stdin) == 0 ||
|
||||||
(*buf != 'y') && (*buf != 'Y'))
|
((*buf != 'y') && (*buf != 'Y')))
|
||||||
{
|
{
|
||||||
puts("\nOK, aborting database drop!");
|
puts("\nOK, aborting database drop!");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -55,6 +55,7 @@ void Twofish::Process(byte* out, const byte* in, word32 sz)
|
|||||||
in += BLOCK_SIZE;
|
in += BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
else if (mode_ == CBC)
|
else if (mode_ == CBC)
|
||||||
|
{
|
||||||
if (dir_ == ENCRYPTION)
|
if (dir_ == ENCRYPTION)
|
||||||
while (blocks--) {
|
while (blocks--) {
|
||||||
r_[0] ^= *(word32*)in;
|
r_[0] ^= *(word32*)in;
|
||||||
@ -83,6 +84,7 @@ void Twofish::Process(byte* out, const byte* in, word32 sz)
|
|||||||
in += BLOCK_SIZE;
|
in += BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // DO_TWOFISH_ASM
|
#endif // DO_TWOFISH_ASM
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ handler.o: handler.cc
|
|||||||
# found to append fileslists that collected by configure
|
# found to append fileslists that collected by configure
|
||||||
# to the sources list
|
# to the sources list
|
||||||
|
|
||||||
ha_federated.o:ha_federated.cc
|
ha_federatedx.o:ha_federatedx.cc
|
||||||
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
|
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
|
||||||
|
|
||||||
ha_heap.o:ha_heap.cc
|
ha_heap.o:ha_heap.cc
|
||||||
|
@ -127,7 +127,6 @@ my $path_config_file; # The generated config file, var/my.cnf
|
|||||||
our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
|
our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
|
||||||
|
|
||||||
my $DEFAULT_SUITES= "binlog,federated,main,maria,rpl,innodb,parts";
|
my $DEFAULT_SUITES= "binlog,federated,main,maria,rpl,innodb,parts";
|
||||||
my $opt_suites;
|
|
||||||
|
|
||||||
our $opt_usage;
|
our $opt_usage;
|
||||||
our $opt_list_options;
|
our $opt_list_options;
|
||||||
|
@ -9,4 +9,5 @@
|
|||||||
# Do not use any TAB characters for whitespace.
|
# Do not use any TAB characters for whitespace.
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
federated_transactions : Bug#29523 Transactions do not work
|
federated_server : needs fixup
|
||||||
|
|
||||||
|
@ -47,9 +47,10 @@ CREATE TABLE federated.t1 (
|
|||||||
)
|
)
|
||||||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||||
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t3';
|
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t3';
|
||||||
SELECT * FROM federated.t1;
|
ERROR HY000: Can't create federated table. Foreign data src error: database: 'federated' username: 'root' hostname: '127.0.0.1'
|
||||||
ERROR HY000: The foreign data source you are trying to reference does not exist. Data source error: error: 1146 'Table 'federated.t3' doesn't exist'
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP TABLE federated.t1;
|
Warnings:
|
||||||
|
Note 1051 Unknown table 't1'
|
||||||
CREATE TABLE federated.t1 (
|
CREATE TABLE federated.t1 (
|
||||||
`id` int(20) NOT NULL,
|
`id` int(20) NOT NULL,
|
||||||
`group` int NOT NULL default 0,
|
`group` int NOT NULL default 0,
|
||||||
@ -59,9 +60,10 @@ CREATE TABLE federated.t1 (
|
|||||||
)
|
)
|
||||||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||||
CONNECTION='mysql://user:pass@127.0.0.1:SLAVE_PORT/federated/t1';
|
CONNECTION='mysql://user:pass@127.0.0.1:SLAVE_PORT/federated/t1';
|
||||||
SELECT * FROM federated.t1;
|
ERROR HY000: Can't create federated table. Foreign data src error: database: 'federated' username: 'user' hostname: '127.0.0.1'
|
||||||
ERROR HY000: Unable to connect to foreign data source: Access denied for user 'user'@'localhost' (using password: YES)
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP TABLE federated.t1;
|
Warnings:
|
||||||
|
Note 1051 Unknown table 't1'
|
||||||
CREATE TABLE federated.t1 (
|
CREATE TABLE federated.t1 (
|
||||||
`id` int(20) NOT NULL,
|
`id` int(20) NOT NULL,
|
||||||
`group` int NOT NULL default 0,
|
`group` int NOT NULL default 0,
|
||||||
@ -1944,15 +1946,7 @@ Bug#18287 create federated table always times out, error 1159 ' '
|
|||||||
|
|
||||||
Test that self-references work
|
Test that self-references work
|
||||||
|
|
||||||
create table federated.t1 (a int primary key);
|
fix LOCK_open before reenabling test for Bug#18287
|
||||||
create table federated.t2 (a int primary key)
|
|
||||||
ENGINE=FEDERATED
|
|
||||||
connection='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
|
|
||||||
insert into federated.t1 (a) values (1);
|
|
||||||
select * from federated.t2;
|
|
||||||
a
|
|
||||||
1
|
|
||||||
drop table federated.t1, federated.t2;
|
|
||||||
CREATE TABLE federated.t1 (a INT PRIMARY KEY) DEFAULT CHARSET=utf8;
|
CREATE TABLE federated.t1 (a INT PRIMARY KEY) DEFAULT CHARSET=utf8;
|
||||||
CREATE TABLE federated.t1 (a INT PRIMARY KEY)
|
CREATE TABLE federated.t1 (a INT PRIMARY KEY)
|
||||||
ENGINE=FEDERATED
|
ENGINE=FEDERATED
|
||||||
@ -1960,13 +1954,11 @@ CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'
|
|||||||
DEFAULT CHARSET=utf8;
|
DEFAULT CHARSET=utf8;
|
||||||
SELECT transactions FROM information_schema.engines WHERE engine="FEDERATED";
|
SELECT transactions FROM information_schema.engines WHERE engine="FEDERATED";
|
||||||
transactions
|
transactions
|
||||||
NO
|
YES
|
||||||
INSERT INTO federated.t1 VALUES (1);
|
INSERT INTO federated.t1 VALUES (1);
|
||||||
SET autocommit=0;
|
SET autocommit=0;
|
||||||
INSERT INTO federated.t1 VALUES (2);
|
INSERT INTO federated.t1 VALUES (2);
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
Warnings:
|
|
||||||
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
|
||||||
SET autocommit=1;
|
SET autocommit=1;
|
||||||
SELECT * FROM federated.t1;
|
SELECT * FROM federated.t1;
|
||||||
a
|
a
|
||||||
@ -2157,6 +2149,6 @@ End of 5.1 tests
|
|||||||
SET @@GLOBAL.CONCURRENT_INSERT= @OLD_MASTER_CONCURRENT_INSERT;
|
SET @@GLOBAL.CONCURRENT_INSERT= @OLD_MASTER_CONCURRENT_INSERT;
|
||||||
SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT;
|
SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
|
@ -57,6 +57,7 @@ CREATE TABLE federated.t1 (
|
|||||||
|
|
||||||
# test non-existant table
|
# test non-existant table
|
||||||
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
--error ER_CANT_CREATE_FEDERATED_TABLE
|
||||||
eval CREATE TABLE federated.t1 (
|
eval CREATE TABLE federated.t1 (
|
||||||
`id` int(20) NOT NULL,
|
`id` int(20) NOT NULL,
|
||||||
`group` int NOT NULL default 0,
|
`group` int NOT NULL default 0,
|
||||||
@ -66,12 +67,11 @@ eval CREATE TABLE federated.t1 (
|
|||||||
)
|
)
|
||||||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||||
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t3';
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t3';
|
||||||
--error ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
SELECT * FROM federated.t1;
|
|
||||||
DROP TABLE federated.t1;
|
|
||||||
|
|
||||||
# test bad user/password
|
# test bad user/password
|
||||||
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
--error ER_CANT_CREATE_FEDERATED_TABLE
|
||||||
eval CREATE TABLE federated.t1 (
|
eval CREATE TABLE federated.t1 (
|
||||||
`id` int(20) NOT NULL,
|
`id` int(20) NOT NULL,
|
||||||
`group` int NOT NULL default 0,
|
`group` int NOT NULL default 0,
|
||||||
@ -81,9 +81,7 @@ eval CREATE TABLE federated.t1 (
|
|||||||
)
|
)
|
||||||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||||
CONNECTION='mysql://user:pass@127.0.0.1:$SLAVE_MYPORT/federated/t1';
|
CONNECTION='mysql://user:pass@127.0.0.1:$SLAVE_MYPORT/federated/t1';
|
||||||
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
SELECT * FROM federated.t1;
|
|
||||||
DROP TABLE federated.t1;
|
|
||||||
|
|
||||||
# # correct connection, same named tables
|
# # correct connection, same named tables
|
||||||
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
@ -1806,6 +1804,8 @@ drop table federated.t1;
|
|||||||
--echo
|
--echo
|
||||||
--echo Test that self-references work
|
--echo Test that self-references work
|
||||||
--echo
|
--echo
|
||||||
|
--echo fix LOCK_open before reenabling test for Bug#18287
|
||||||
|
--disable_parsing
|
||||||
connection slave;
|
connection slave;
|
||||||
create table federated.t1 (a int primary key);
|
create table federated.t1 (a int primary key);
|
||||||
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
@ -1815,7 +1815,7 @@ eval create table federated.t2 (a int primary key)
|
|||||||
insert into federated.t1 (a) values (1);
|
insert into federated.t1 (a) values (1);
|
||||||
select * from federated.t2;
|
select * from federated.t2;
|
||||||
drop table federated.t1, federated.t2;
|
drop table federated.t1, federated.t2;
|
||||||
|
--enable_parsing
|
||||||
#
|
#
|
||||||
# BUG#29875 Disable support for transactions
|
# BUG#29875 Disable support for transactions
|
||||||
#
|
#
|
||||||
|
@ -34,6 +34,6 @@ id name
|
|||||||
DROP TABLE federated.t1;
|
DROP TABLE federated.t1;
|
||||||
DROP TABLE federated.archive_table;
|
DROP TABLE federated.archive_table;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
|
@ -25,6 +25,6 @@ foo bar
|
|||||||
DROP TABLE federated.t1;
|
DROP TABLE federated.t1;
|
||||||
DROP TABLE federated.bug_13118_table;
|
DROP TABLE federated.bug_13118_table;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
|
@ -48,6 +48,6 @@ SET @@GLOBAL.CONCURRENT_INSERT= @OLD_MASTER_CONCURRENT_INSERT;
|
|||||||
DROP TABLE federated.t1;
|
DROP TABLE federated.t1;
|
||||||
SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT;
|
SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
connection master;
|
connection master;
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
|
|
||||||
connection slave;
|
connection slave;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
@ -20,6 +20,6 @@ a b
|
|||||||
drop table federated.t1;
|
drop table federated.t1;
|
||||||
drop table federated.t1;
|
drop table federated.t1;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
DROP DATABASE federated;
|
DROP DATABASE IF EXISTS federated;
|
||||||
|
@ -178,8 +178,8 @@ INSERT INTO db_bogus.t1 VALUES ('2','this is bogus');
|
|||||||
create server 's1' foreign data wrapper 'mysql' options
|
create server 's1' foreign data wrapper 'mysql' options
|
||||||
(HOST '127.0.0.1',
|
(HOST '127.0.0.1',
|
||||||
DATABASE 'db_legitimate',
|
DATABASE 'db_legitimate',
|
||||||
USER 'root',
|
USER 'test_fed',
|
||||||
PASSWORD '',
|
PASSWORD 'foo',
|
||||||
PORT SLAVE_PORT,
|
PORT SLAVE_PORT,
|
||||||
SOCKET '',
|
SOCKET '',
|
||||||
OWNER 'root');
|
OWNER 'root');
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
# Slow test, don't run during staging part
|
# Slow test, don't run during staging part
|
||||||
-- source include/not_staging.inc
|
-- source include/not_staging.inc
|
||||||
|
-- source include/big_test.inc
|
||||||
-- source federated.inc
|
-- source federated.inc
|
||||||
|
|
||||||
connection slave;
|
connection slave;
|
||||||
@ -182,13 +183,17 @@ CREATE TABLE db_bogus.t1 (
|
|||||||
;
|
;
|
||||||
INSERT INTO db_bogus.t1 VALUES ('2','this is bogus');
|
INSERT INTO db_bogus.t1 VALUES ('2','this is bogus');
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
create user test_fed@localhost identified by 'foo';
|
||||||
|
grant all on db_legitimate.* to test_fed@localhost;
|
||||||
|
|
||||||
connection master;
|
connection master;
|
||||||
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
eval create server 's1' foreign data wrapper 'mysql' options
|
eval create server 's1' foreign data wrapper 'mysql' options
|
||||||
(HOST '127.0.0.1',
|
(HOST '127.0.0.1',
|
||||||
DATABASE 'db_legitimate',
|
DATABASE 'db_legitimate',
|
||||||
USER 'root',
|
USER 'test_fed',
|
||||||
PASSWORD '',
|
PASSWORD 'foo',
|
||||||
PORT $SLAVE_MYPORT,
|
PORT $SLAVE_MYPORT,
|
||||||
SOCKET '',
|
SOCKET '',
|
||||||
OWNER 'root');
|
OWNER 'root');
|
||||||
|
@ -1,13 +1,4 @@
|
|||||||
stop slave;
|
|
||||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
|
||||||
reset master;
|
|
||||||
reset slave;
|
|
||||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
|
||||||
start slave;
|
|
||||||
stop slave;
|
|
||||||
DROP DATABASE IF EXISTS federated;
|
|
||||||
CREATE DATABASE federated;
|
CREATE DATABASE federated;
|
||||||
DROP DATABASE IF EXISTS federated;
|
|
||||||
CREATE DATABASE federated;
|
CREATE DATABASE federated;
|
||||||
DROP TABLE IF EXISTS federated.t1;
|
DROP TABLE IF EXISTS federated.t1;
|
||||||
Warnings:
|
Warnings:
|
||||||
|
@ -880,3 +880,17 @@
|
|||||||
fun:nptl_pthread_exit_hack_handler
|
fun:nptl_pthread_exit_hack_handler
|
||||||
fun:start_thread
|
fun:start_thread
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Problem with glibc and gethostbyaddr_r
|
||||||
|
#
|
||||||
|
|
||||||
|
{
|
||||||
|
libc_res_nsend: Conditional jump or move depends on uninitialised value
|
||||||
|
Memcheck:Cond
|
||||||
|
fun: __libc_res_nsend
|
||||||
|
fun: __libc_res_nquery
|
||||||
|
obj: /lib64/libnss_dns-*so)
|
||||||
|
obj: /lib64/libnss_dns-*so)
|
||||||
|
fun: gethostbyaddr_r
|
||||||
|
}
|
||||||
|
7
storage/federated/README
Normal file
7
storage/federated/README
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
The files in this directory are not used by MariaDB
|
||||||
|
|
||||||
|
MariaDB uses the new federated storage engine that can be found in the
|
||||||
|
federatedx directory.
|
||||||
|
|
||||||
|
This directory is only kept around to make it easy to merge code from the
|
||||||
|
MySQL source repositories that uses the old and disabled federated code.
|
11
storage/federatedx/AUTHORS
Normal file
11
storage/federatedx/AUTHORS
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
FederatedX
|
||||||
|
|
||||||
|
Patrick Galbraith <patg@patg.net> - Federated
|
||||||
|
|
||||||
|
Pluggable Storage Engine Skeleton setup
|
||||||
|
|
||||||
|
Brian Aker <brian@mysql.com> | <brian@tangent.org> - Original Design
|
||||||
|
Calvin Sun - Windows Support
|
||||||
|
Brian Miezejewski - Bug fixes
|
||||||
|
Antony T Curtis - Help in inital development, transactions and various help
|
||||||
|
Michael Widenius - Bug fixes and some simple early optimizations
|
3
storage/federatedx/CMakeFiles.txt
Normal file
3
storage/federatedx/CMakeFiles.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
|
||||||
|
SET(FEDERATED_SOURCES ha_federatedx.cc)
|
||||||
|
MYSQL_STORAGE_ENGINE(FEDERATED)
|
18
storage/federatedx/ChangeLog
Normal file
18
storage/federatedx/ChangeLog
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
0.2 - Thu March 8 00:00:00 EST 2008
|
||||||
|
|
||||||
|
- Fixed bug #30051 "CREATE TABLE does not connect and check existence of remote table"
|
||||||
|
Modified "real_connect" to take a share and create flag to in order to not rely
|
||||||
|
on any settings that are later instantiated and/or set by get_share
|
||||||
|
Also, put logic in the code to not attempt this if a localhost. There's an annoying
|
||||||
|
functionality that if federated tries to connect to itself during creater table, you
|
||||||
|
get 1159 error (timeout) - only when local. This prevents having this functionality
|
||||||
|
and is probably part of the reason it was removed.
|
||||||
|
|
||||||
|
0.1 - Thu Feb 1 00:00:00 EST 2008
|
||||||
|
|
||||||
|
- This is the FederatedX Storage Engine,
|
||||||
|
first release.
|
||||||
|
- Added documentation
|
||||||
|
- Added simple test and README file to explain
|
||||||
|
how to run the test
|
||||||
|
- Added FAQ
|
40
storage/federatedx/FAQ
Normal file
40
storage/federatedx/FAQ
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
Q. What is the FederatedX pluggable storage engine?
|
||||||
|
|
||||||
|
A. It is a fork of the Federated Storage Engine that Brian Aker and I
|
||||||
|
(Patrick Galbraith) developed originally . It is a storage engine that
|
||||||
|
uses a client connection to a remote MySQL data source as its data
|
||||||
|
source instead of a local file on disk.
|
||||||
|
|
||||||
|
Q. Why did you fork from Federated?
|
||||||
|
|
||||||
|
A. To enhance the storage engine independently of the
|
||||||
|
MySQL Server release schedule. Many people have been
|
||||||
|
mentioning their dissatisfaction with the limitations
|
||||||
|
of Federated. I think the engine is a great concept and
|
||||||
|
have a sense of obligation to continue to improve it.
|
||||||
|
There are some patches already that are in dire need
|
||||||
|
of being applied and tested.
|
||||||
|
|
||||||
|
Q. What do you plan to do with FederatedX?
|
||||||
|
|
||||||
|
A. Many things need addressing:
|
||||||
|
|
||||||
|
- Outstanding bugs
|
||||||
|
- How do deal with huge result sets
|
||||||
|
- Pushdown conditions (being able to pass things like LIMIT
|
||||||
|
to the remote connection to keep from returning huge
|
||||||
|
result sets).
|
||||||
|
- Better transactional support
|
||||||
|
- Other connection mechanisms (ODBC, JDBC, native drivers
|
||||||
|
of other RDBMSs)
|
||||||
|
|
||||||
|
Q. What FederatedX is and is not?
|
||||||
|
|
||||||
|
A. FederatedX is not yet a complete "federated" solution in
|
||||||
|
the sense that other venders have developed (IBM, etc). It
|
||||||
|
is essentially a networked storage engine. It is my hope
|
||||||
|
to make it a real federated solution.
|
||||||
|
|
||||||
|
Q. In which MySQL distributions/forks/branches can I find FederateX
|
||||||
|
|
||||||
|
A. MariaDB (http://www.mariadb.com)
|
64
storage/federatedx/Makefile.am
Normal file
64
storage/federatedx/Makefile.am
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# Used to build Makefile.in
|
||||||
|
|
||||||
|
MYSQLDATAdir = $(localstatedir)
|
||||||
|
MYSQLSHAREdir = $(pkgdatadir)
|
||||||
|
MYSQLBASEdir= $(prefix)
|
||||||
|
MYSQLLIBdir= $(pkglibdir)
|
||||||
|
pkgplugindir = $(pkglibdir)/plugin
|
||||||
|
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
|
||||||
|
-I$(top_srcdir)/regex \
|
||||||
|
-I$(top_srcdir)/sql \
|
||||||
|
-I$(srcdir)
|
||||||
|
WRAPLIBS=
|
||||||
|
|
||||||
|
LDADD =
|
||||||
|
|
||||||
|
DEFS = @DEFS@
|
||||||
|
|
||||||
|
noinst_HEADERS = ha_federatedx.h federatedx_probes.h
|
||||||
|
|
||||||
|
EXTRA_LTLIBRARIES = ha_federatedx.la
|
||||||
|
pkgplugin_LTLIBRARIES = @plugin_federated_shared_target@
|
||||||
|
ha_federatedx_la_LDFLAGS = -module -rpath $(pkgplugindir)
|
||||||
|
ha_federatedx_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||||
|
ha_federatedx_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||||
|
ha_federatedx_la_SOURCES = ha_federatedx.cc
|
||||||
|
|
||||||
|
|
||||||
|
EXTRA_LIBRARIES = libfederatedx.a
|
||||||
|
noinst_LIBRARIES = @plugin_federated_static_target@
|
||||||
|
libfederatedx_a_CXXFLAGS = $(AM_CFLAGS)
|
||||||
|
libfederatedx_a_CFLAGS = $(AM_CFLAGS)
|
||||||
|
libfederatedx_a_SOURCES= ha_federatedx.cc federatedx_txn.cc \
|
||||||
|
federatedx_io.cc federatedx_io_null.cc \
|
||||||
|
federatedx_io_mysql.cc
|
||||||
|
|
||||||
|
EXTRA_DIST = CMakeLists.txt plug.in ha_federatedx.h \
|
||||||
|
federatedx_probes.d
|
||||||
|
|
||||||
|
ha_federatedx_la_SOURCES = ha_federatedx.cc federatedx_txn.cc \
|
||||||
|
federatedx_io.cc federatedx_io_null.cc \
|
||||||
|
federatedx_io_mysql.cc $(top_srcdir)/mysys/string.c
|
||||||
|
ha_federatedx_la_LIBADD =
|
||||||
|
|
||||||
|
#DTRACE = @DTRACE@
|
||||||
|
#DTRACEFLAGS = @DTRACEFLAGS@
|
||||||
|
#DTRACEFILES = .libs/libfederatedx_engine_la-ha_federatedx.o
|
||||||
|
|
||||||
|
# #if HAVE_DTRACE
|
||||||
|
# # libfederatedx_engine_la_LIBADD += federatedx_probes.o
|
||||||
|
# #endif
|
||||||
|
|
||||||
|
# federatedx_probes.h: federatedx_probes.d
|
||||||
|
# $(DTRACE) $(DTRACEFLAGS) -h -s federatedx_probes.d
|
||||||
|
# mv federatedx_probes.h federatedx_probes.h.bak
|
||||||
|
# sed "s/#include <unistd.h>//g" federatedx_probes.h.bak > federatedx_probes.h
|
||||||
|
# rm federatedx_probes.h.bak
|
||||||
|
|
||||||
|
#federatedx_probes.o:
|
||||||
|
# $(DTRACE) $(DTRACEFLAGS) -G -s federatedx_probes.d $(DTRACEFILES)
|
||||||
|
|
||||||
|
# End
|
||||||
|
|
||||||
|
# Don't update the files from bitkeeper
|
||||||
|
%::SCCS/s.%
|
33
storage/federatedx/README
Normal file
33
storage/federatedx/README
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
This is the FederatedX Storage Engine, developed as an external storage engine.
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
|
||||||
|
The following is only relevant if you use it for MySQL. MariaDB already comes
|
||||||
|
with the latest version of FederatedX.
|
||||||
|
|
||||||
|
To install, grab a copy of the mysql source code and run this:
|
||||||
|
|
||||||
|
./configure --with-mysql=/path/to/src/mysql-5.x --libdir=/usr/local/lib/mysql/
|
||||||
|
|
||||||
|
make install
|
||||||
|
|
||||||
|
And then inside of MySQL:
|
||||||
|
|
||||||
|
mysql> INSTALL PLUGIN federatedx SONAME 'libfederatedx_engine.so';
|
||||||
|
|
||||||
|
mysql> CREATE TABLE `d` (`a` varchar(125), b text, primary key(a)) ENGINE=FEDERATEDX CONNECTION="mysql://root@host/schema/table"
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
mysql> CREATE TABLE `d` (`a` varchar(125), b text, primary key(a)) ENGINE=FEDERATEDX CONNECTION="server" CHARSET=latin1;
|
||||||
|
|
||||||
|
You will probably need to edit the Makefile.am in the src/ tree if you want
|
||||||
|
to build on anything other then Linux (and the Makefile assumes that the
|
||||||
|
server was not compiled for debug). The reason for the two possible
|
||||||
|
configure lines is that libdir is dependent on where MySQL was installed. If
|
||||||
|
you run the "INSTALL PLUGIN ..." and you get a file not found, check that
|
||||||
|
your configured this directory correctly.
|
||||||
|
|
||||||
|
For Solaris you can enable DTrace probes by adding to configure
|
||||||
|
--enable-dtrace
|
||||||
|
|
23
storage/federatedx/README.windows
Normal file
23
storage/federatedx/README.windows
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
The following files are changed in order to build a new engine on Windows:
|
||||||
|
|
||||||
|
- Update win\configure.js with
|
||||||
|
case "WITH_FEDERATEDX_STORAGE_ENGINE":
|
||||||
|
to make sure it will pass WITH_FEDERATEDX_STORAGE_ENGINE in.
|
||||||
|
|
||||||
|
- Update CMakeFiles.txt under mysql root:
|
||||||
|
IF(WITH_FEDERATEDX_STORAGE_ENGINE)
|
||||||
|
ADD_DEFINITIONS(-D WITH_FEDERATEDX_STORAGE_ENGINE)
|
||||||
|
SET (mysql_plugin_defs
|
||||||
|
"${mysql_plugin_defs},builtin_skeleton_plugin")
|
||||||
|
ENDIF(WITH_FEDERATEDX_STORAGE_ENGINE)
|
||||||
|
|
||||||
|
and,
|
||||||
|
|
||||||
|
IF(WITH_FEDERATEDX_STORAGE_ENGINE)
|
||||||
|
ADD_SUBDIRECTORY(storage/skeleton/src)
|
||||||
|
ENDIF(WITH_FEDERATEDX_STORAGE_ENGINE)
|
||||||
|
|
||||||
|
- Update CMakeFiles.txt under sql:
|
||||||
|
IF(WITH_FEDERATEDX_STORAGE_ENGINE)
|
||||||
|
TARGET_LINK_LIBRARIES(mysqld skeleton)
|
||||||
|
ENDIF(WITH_FEDERATEDX_STORAGE_ENGINE)
|
30
storage/federatedx/TODO
Normal file
30
storage/federatedx/TODO
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
Features
|
||||||
|
|
||||||
|
* Add Pushdown conditions
|
||||||
|
* Add other network driver interfaces
|
||||||
|
* Handle large result sets
|
||||||
|
* Auto-discovery of tables on foreign data sources
|
||||||
|
|
||||||
|
Bugs (http://bugs.mysql.com)
|
||||||
|
|
||||||
|
20026 2006-05-23 FEDERATED lacks support for auto_increment_increment and auto_increment_offset
|
||||||
|
20724 2006-06-27 FEDERATED does not honour SET INSERT_ID
|
||||||
|
28269 2007-05-06 Any FEDERATED engine fails to quote reserved words for field names
|
||||||
|
25509 2007-01-10 Federated: Failure with non-ASCII characters
|
||||||
|
26697 2007-02-27 Every query to a federated table results in a full scan of MyISAM table.
|
||||||
|
21360 2006-07-31 Microsoft Windows (Windows/Linux) mysqldump error on federated tables
|
||||||
|
34189 2008-01-31 Any ALTER TABLE t1 ENGINE=FEDERATED CONNECTION='connectionString' on MyISAM fails
|
||||||
|
31757 2007-10-22 Any Federated tables break replication Antony Curtis
|
||||||
|
33953 2008-01-21 Any mysqld dies on search federated table using nullable index with < or <= operator
|
||||||
|
34015 2008-01-23 Linux Problems with float fields using federated tables
|
||||||
|
21583 2006-08-11 Linux (Linux) Federated table returns broken strings.
|
||||||
|
33702 2008-01-05 Accessing a federated table with a non existing server returns random error code
|
||||||
|
25512 2007-01-10 Federated: CREATE failures
|
||||||
|
32426 2007-11-16 Any FEDERATED query returns corrupt results for ORDER BY on a TEXT field
|
||||||
|
25510 2007-01-10 Federated: double trigger activation
|
||||||
|
33250 2007-12-14 SELECT * FROM really_big_federated_table eats lots of virtual memory (OOM)
|
||||||
|
14874 2005-11-11 Error 2013: Lost connection to MySQL server with Federated table
|
||||||
|
25508 2007-01-10 Federated: Failure to Remove Partitioning
|
||||||
|
27180 2007-03-15 #1030 - Got error 1 from storage engine with big tables
|
||||||
|
33947 2008-01-20 Any Join on Federated tables with Unique index and IS NOT NULL crashes server
|
||||||
|
30051 (fixed) CREATE TABLE does not connect and check existence of remote table
|
103
storage/federatedx/federatedx_io.cc
Normal file
103
storage/federatedx/federatedx_io.cc
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2007, Antony T Curtis
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Neither the name of FederatedX nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*#define MYSQL_SERVER 1*/
|
||||||
|
#include "mysql_priv.h"
|
||||||
|
#include <mysql/plugin.h>
|
||||||
|
|
||||||
|
#include "ha_federatedx.h"
|
||||||
|
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
|
#pragma implementation // gcc: Class implementation
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef federatedx_io *(*instantiate_io_type)(MEM_ROOT *server_root,
|
||||||
|
FEDERATEDX_SERVER *server);
|
||||||
|
struct io_schemes_st
|
||||||
|
{
|
||||||
|
const char *scheme;
|
||||||
|
instantiate_io_type instantiate;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const io_schemes_st federated_io_schemes[] =
|
||||||
|
{
|
||||||
|
{ "mysql", &instantiate_io_mysql },
|
||||||
|
{ "null", instantiate_io_null } /* must be last element */
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint federated_io_schemes_count= array_elements(federated_io_schemes);
|
||||||
|
|
||||||
|
federatedx_io::federatedx_io(FEDERATEDX_SERVER *aserver)
|
||||||
|
: server(aserver), owner_ptr(0), txn_next(0), idle_next(0),
|
||||||
|
active(FALSE), busy(FALSE), readonly(TRUE)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("federatedx_io::federatedx_io");
|
||||||
|
DBUG_ASSERT(server);
|
||||||
|
|
||||||
|
safe_mutex_assert_owner(&server->mutex);
|
||||||
|
server->io_count++;
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
federatedx_io::~federatedx_io()
|
||||||
|
{
|
||||||
|
DBUG_ENTER("federatedx_io::~federatedx_io");
|
||||||
|
|
||||||
|
server->io_count--;
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool federatedx_io::handles_scheme(const char *scheme)
|
||||||
|
{
|
||||||
|
const io_schemes_st *ptr = federated_io_schemes;
|
||||||
|
const io_schemes_st *end = ptr + array_elements(federated_io_schemes);
|
||||||
|
while (ptr != end && strcasecmp(scheme, ptr->scheme))
|
||||||
|
++ptr;
|
||||||
|
return ptr != end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
federatedx_io *federatedx_io::construct(MEM_ROOT *server_root,
|
||||||
|
FEDERATEDX_SERVER *server)
|
||||||
|
{
|
||||||
|
const io_schemes_st *ptr = federated_io_schemes;
|
||||||
|
const io_schemes_st *end = ptr + (array_elements(federated_io_schemes) - 1);
|
||||||
|
while (ptr != end && strcasecmp(server->scheme, ptr->scheme))
|
||||||
|
++ptr;
|
||||||
|
return ptr->instantiate(server_root, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
592
storage/federatedx/federatedx_io_mysql.cc
Normal file
592
storage/federatedx/federatedx_io_mysql.cc
Normal file
@ -0,0 +1,592 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2007, Antony T Curtis
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Neither the name of FederatedX nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*#define MYSQL_SERVER 1*/
|
||||||
|
#include "mysql_priv.h"
|
||||||
|
#include <mysql/plugin.h>
|
||||||
|
|
||||||
|
#include "ha_federatedx.h"
|
||||||
|
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
|
#pragma implementation // gcc: Class implementation
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define SAVEPOINT_REALIZED 1
|
||||||
|
#define SAVEPOINT_RESTRICT 2
|
||||||
|
#define SAVEPOINT_EMITTED 4
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct federatedx_savepoint
|
||||||
|
{
|
||||||
|
ulong level;
|
||||||
|
uint flags;
|
||||||
|
} SAVEPT;
|
||||||
|
|
||||||
|
|
||||||
|
class federatedx_io_mysql :public federatedx_io
|
||||||
|
{
|
||||||
|
MYSQL mysql; /* MySQL connection */
|
||||||
|
DYNAMIC_ARRAY savepoints;
|
||||||
|
bool requested_autocommit;
|
||||||
|
bool actual_autocommit;
|
||||||
|
|
||||||
|
int actual_query(const char *buffer, uint length);
|
||||||
|
bool test_all_restrict() const;
|
||||||
|
public:
|
||||||
|
federatedx_io_mysql(FEDERATEDX_SERVER *);
|
||||||
|
~federatedx_io_mysql();
|
||||||
|
|
||||||
|
int simple_query(const char *fmt, ...);
|
||||||
|
int query(const char *buffer, uint length);
|
||||||
|
virtual FEDERATEDX_IO_RESULT *store_result();
|
||||||
|
|
||||||
|
virtual size_t max_query_size() const;
|
||||||
|
|
||||||
|
virtual my_ulonglong affected_rows() const;
|
||||||
|
virtual my_ulonglong last_insert_id() const;
|
||||||
|
|
||||||
|
virtual int error_code();
|
||||||
|
virtual const char *error_str();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
int commit();
|
||||||
|
int rollback();
|
||||||
|
|
||||||
|
int savepoint_set(ulong sp);
|
||||||
|
ulong savepoint_release(ulong sp);
|
||||||
|
ulong savepoint_rollback(ulong sp);
|
||||||
|
void savepoint_restrict(ulong sp);
|
||||||
|
|
||||||
|
ulong last_savepoint() const;
|
||||||
|
ulong actual_savepoint() const;
|
||||||
|
bool is_autocommit() const;
|
||||||
|
|
||||||
|
bool table_metadata(ha_statistics *stats, const char *table_name,
|
||||||
|
uint table_name_length, uint flag);
|
||||||
|
|
||||||
|
/* resultset operations */
|
||||||
|
|
||||||
|
virtual void free_result(FEDERATEDX_IO_RESULT *io_result);
|
||||||
|
virtual unsigned int get_num_fields(FEDERATEDX_IO_RESULT *io_result);
|
||||||
|
virtual my_ulonglong get_num_rows(FEDERATEDX_IO_RESULT *io_result);
|
||||||
|
virtual FEDERATEDX_IO_ROW *fetch_row(FEDERATEDX_IO_RESULT *io_result);
|
||||||
|
virtual ulong *fetch_lengths(FEDERATEDX_IO_RESULT *io_result);
|
||||||
|
virtual const char *get_column_data(FEDERATEDX_IO_ROW *row,
|
||||||
|
unsigned int column);
|
||||||
|
virtual bool is_column_null(const FEDERATEDX_IO_ROW *row,
|
||||||
|
unsigned int column) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
federatedx_io *instantiate_io_mysql(MEM_ROOT *server_root,
|
||||||
|
FEDERATEDX_SERVER *server)
|
||||||
|
{
|
||||||
|
return new (server_root) federatedx_io_mysql(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
federatedx_io_mysql::federatedx_io_mysql(FEDERATEDX_SERVER *aserver)
|
||||||
|
: federatedx_io(aserver),
|
||||||
|
requested_autocommit(TRUE), actual_autocommit(TRUE)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::federatedx_io_mysql");
|
||||||
|
|
||||||
|
bzero(&mysql, sizeof(MYSQL));
|
||||||
|
bzero(&savepoints, sizeof(DYNAMIC_ARRAY));
|
||||||
|
|
||||||
|
my_init_dynamic_array(&savepoints, sizeof(SAVEPT), 16, 16);
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
federatedx_io_mysql::~federatedx_io_mysql()
|
||||||
|
{
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::~federatedx_io_mysql");
|
||||||
|
|
||||||
|
mysql_close(&mysql);
|
||||||
|
delete_dynamic(&savepoints);
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void federatedx_io_mysql::reset()
|
||||||
|
{
|
||||||
|
reset_dynamic(&savepoints);
|
||||||
|
set_active(FALSE);
|
||||||
|
|
||||||
|
requested_autocommit= TRUE;
|
||||||
|
mysql.reconnect= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_io_mysql::commit()
|
||||||
|
{
|
||||||
|
int error= 0;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::commit");
|
||||||
|
|
||||||
|
if (!actual_autocommit && (error= actual_query("COMMIT", 6)))
|
||||||
|
rollback();
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
int federatedx_io_mysql::rollback()
|
||||||
|
{
|
||||||
|
int error= 0;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::rollback");
|
||||||
|
|
||||||
|
if (!actual_autocommit)
|
||||||
|
error= actual_query("ROLLBACK", 8);
|
||||||
|
else
|
||||||
|
error= ER_WARNING_NOT_COMPLETE_ROLLBACK;
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong federatedx_io_mysql::last_savepoint() const
|
||||||
|
{
|
||||||
|
SAVEPT *savept= NULL;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::last_savepoint");
|
||||||
|
|
||||||
|
if (savepoints.elements)
|
||||||
|
savept= dynamic_element(&savepoints, savepoints.elements - 1, SAVEPT *);
|
||||||
|
|
||||||
|
DBUG_RETURN(savept ? savept->level : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong federatedx_io_mysql::actual_savepoint() const
|
||||||
|
{
|
||||||
|
SAVEPT *savept= NULL;
|
||||||
|
uint index= savepoints.elements;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::last_savepoint");
|
||||||
|
|
||||||
|
while (index)
|
||||||
|
{
|
||||||
|
savept= dynamic_element(&savepoints, --index, SAVEPT *);
|
||||||
|
if (savept->flags & SAVEPOINT_REALIZED)
|
||||||
|
break;
|
||||||
|
savept= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(savept ? savept->level : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool federatedx_io_mysql::is_autocommit() const
|
||||||
|
{
|
||||||
|
return actual_autocommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_io_mysql::savepoint_set(ulong sp)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
SAVEPT savept;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::savepoint_set");
|
||||||
|
DBUG_PRINT("info",("savepoint=%lu", sp));
|
||||||
|
DBUG_ASSERT(sp > last_savepoint());
|
||||||
|
|
||||||
|
savept.level= sp;
|
||||||
|
savept.flags= 0;
|
||||||
|
|
||||||
|
if ((error= insert_dynamic(&savepoints, (uchar*) &savept) ? -1 : 0))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
set_active(TRUE);
|
||||||
|
mysql.reconnect= 0;
|
||||||
|
requested_autocommit= FALSE;
|
||||||
|
|
||||||
|
err:
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong federatedx_io_mysql::savepoint_release(ulong sp)
|
||||||
|
{
|
||||||
|
SAVEPT *savept, *last= NULL;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::savepoint_release");
|
||||||
|
DBUG_PRINT("info",("savepoint=%lu", sp));
|
||||||
|
|
||||||
|
while (savepoints.elements)
|
||||||
|
{
|
||||||
|
savept= dynamic_element(&savepoints, savepoints.elements - 1, SAVEPT *);
|
||||||
|
if (savept->level < sp)
|
||||||
|
break;
|
||||||
|
if ((savept->flags & (SAVEPOINT_REALIZED |
|
||||||
|
SAVEPOINT_RESTRICT)) == SAVEPOINT_REALIZED)
|
||||||
|
last= savept;
|
||||||
|
savepoints.elements--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last)
|
||||||
|
{
|
||||||
|
char buffer[STRING_BUFFER_USUAL_SIZE];
|
||||||
|
int length= my_snprintf(buffer, sizeof(buffer),
|
||||||
|
"RELEASE SAVEPOINT save%lu", last->level);
|
||||||
|
actual_query(buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(last_savepoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong federatedx_io_mysql::savepoint_rollback(ulong sp)
|
||||||
|
{
|
||||||
|
SAVEPT *savept;
|
||||||
|
uint index;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::savepoint_release");
|
||||||
|
DBUG_PRINT("info",("savepoint=%lu", sp));
|
||||||
|
|
||||||
|
while (savepoints.elements)
|
||||||
|
{
|
||||||
|
savept= dynamic_element(&savepoints, savepoints.elements - 1, SAVEPT *);
|
||||||
|
if (savept->level <= sp)
|
||||||
|
break;
|
||||||
|
savepoints.elements--;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index= savepoints.elements, savept= NULL; index;)
|
||||||
|
{
|
||||||
|
savept= dynamic_element(&savepoints, --index, SAVEPT *);
|
||||||
|
if (savept->flags & SAVEPOINT_REALIZED)
|
||||||
|
break;
|
||||||
|
savept= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (savept && !(savept->flags & SAVEPOINT_RESTRICT))
|
||||||
|
{
|
||||||
|
char buffer[STRING_BUFFER_USUAL_SIZE];
|
||||||
|
int length= my_snprintf(buffer, sizeof(buffer),
|
||||||
|
"ROLLBACK TO SAVEPOINT save%lu", savept->level);
|
||||||
|
actual_query(buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(last_savepoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void federatedx_io_mysql::savepoint_restrict(ulong sp)
|
||||||
|
{
|
||||||
|
SAVEPT *savept;
|
||||||
|
uint index= savepoints.elements;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::savepoint_restrict");
|
||||||
|
|
||||||
|
while (index)
|
||||||
|
{
|
||||||
|
savept= dynamic_element(&savepoints, --index, SAVEPT *);
|
||||||
|
if (savept->level > sp)
|
||||||
|
continue;
|
||||||
|
if (savept->level < sp)
|
||||||
|
break;
|
||||||
|
savept->flags|= SAVEPOINT_RESTRICT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_io_mysql::simple_query(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char buffer[STRING_BUFFER_USUAL_SIZE];
|
||||||
|
int length, error;
|
||||||
|
va_list arg;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::simple_query");
|
||||||
|
|
||||||
|
va_start(arg, fmt);
|
||||||
|
length= my_vsnprintf(buffer, sizeof(buffer), fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
|
||||||
|
error= query(buffer, length);
|
||||||
|
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool federatedx_io_mysql::test_all_restrict() const
|
||||||
|
{
|
||||||
|
bool result= FALSE;
|
||||||
|
SAVEPT *savept;
|
||||||
|
uint index= savepoints.elements;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::test_all_restrict");
|
||||||
|
|
||||||
|
while (index)
|
||||||
|
{
|
||||||
|
savept= dynamic_element(&savepoints, --index, SAVEPT *);
|
||||||
|
if ((savept->flags & (SAVEPOINT_REALIZED |
|
||||||
|
SAVEPOINT_RESTRICT)) == SAVEPOINT_REALIZED ||
|
||||||
|
(savept->flags & SAVEPOINT_EMITTED))
|
||||||
|
DBUG_RETURN(FALSE);
|
||||||
|
if (savept->flags & SAVEPOINT_RESTRICT)
|
||||||
|
result= TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_io_mysql::query(const char *buffer, uint length)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
bool wants_autocommit= requested_autocommit | is_readonly();
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::query");
|
||||||
|
|
||||||
|
if (!wants_autocommit && test_all_restrict())
|
||||||
|
wants_autocommit= TRUE;
|
||||||
|
|
||||||
|
if (wants_autocommit != actual_autocommit)
|
||||||
|
{
|
||||||
|
if ((error= actual_query(wants_autocommit ? "SET AUTOCOMMIT=1"
|
||||||
|
: "SET AUTOCOMMIT=0", 16)))
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
mysql.reconnect= wants_autocommit ? 1 : 0;
|
||||||
|
actual_autocommit= wants_autocommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!actual_autocommit && last_savepoint() != actual_savepoint())
|
||||||
|
{
|
||||||
|
SAVEPT *savept= dynamic_element(&savepoints, savepoints.elements - 1,
|
||||||
|
SAVEPT *);
|
||||||
|
if (!(savept->flags & SAVEPOINT_RESTRICT))
|
||||||
|
{
|
||||||
|
char buf[STRING_BUFFER_USUAL_SIZE];
|
||||||
|
int len= my_snprintf(buf, sizeof(buf),
|
||||||
|
"SAVEPOINT save%lu", savept->level);
|
||||||
|
if ((error= actual_query(buf, len)))
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
set_active(TRUE);
|
||||||
|
savept->flags|= SAVEPOINT_EMITTED;
|
||||||
|
}
|
||||||
|
savept->flags|= SAVEPOINT_REALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(error= actual_query(buffer, length)))
|
||||||
|
set_active(is_active() || !actual_autocommit);
|
||||||
|
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_io_mysql::actual_query(const char *buffer, uint length)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::actual_query");
|
||||||
|
|
||||||
|
if (!mysql.master)
|
||||||
|
{
|
||||||
|
if (!(mysql_init(&mysql)))
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
BUG# 17044 Federated Storage Engine is not UTF8 clean
|
||||||
|
Add set names to whatever charset the table is at open
|
||||||
|
of table
|
||||||
|
*/
|
||||||
|
/* this sets the csname like 'set names utf8' */
|
||||||
|
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, get_charsetname());
|
||||||
|
|
||||||
|
if (!mysql_real_connect(&mysql,
|
||||||
|
get_hostname(),
|
||||||
|
get_username(),
|
||||||
|
get_password(),
|
||||||
|
get_database(),
|
||||||
|
get_port(),
|
||||||
|
get_socket(), 0))
|
||||||
|
DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE);
|
||||||
|
mysql.reconnect= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
error= mysql_real_query(&mysql, buffer, length);
|
||||||
|
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t federatedx_io_mysql::max_query_size() const
|
||||||
|
{
|
||||||
|
return mysql.net.max_packet_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_ulonglong federatedx_io_mysql::affected_rows() const
|
||||||
|
{
|
||||||
|
return mysql.affected_rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_ulonglong federatedx_io_mysql::last_insert_id() const
|
||||||
|
{
|
||||||
|
return mysql.last_used_con->insert_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_io_mysql::error_code()
|
||||||
|
{
|
||||||
|
return mysql_errno(&mysql);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *federatedx_io_mysql::error_str()
|
||||||
|
{
|
||||||
|
return mysql_error(&mysql);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FEDERATEDX_IO_RESULT *federatedx_io_mysql::store_result()
|
||||||
|
{
|
||||||
|
FEDERATEDX_IO_RESULT *result;
|
||||||
|
DBUG_ENTER("federatedx_io_mysql::store_result");
|
||||||
|
|
||||||
|
result= (FEDERATEDX_IO_RESULT *) mysql_store_result(&mysql);
|
||||||
|
|
||||||
|
DBUG_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void federatedx_io_mysql::free_result(FEDERATEDX_IO_RESULT *io_result)
|
||||||
|
{
|
||||||
|
mysql_free_result((MYSQL_RES *) io_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int federatedx_io_mysql::get_num_fields(FEDERATEDX_IO_RESULT *io_result)
|
||||||
|
{
|
||||||
|
return mysql_num_fields((MYSQL_RES *) io_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_ulonglong federatedx_io_mysql::get_num_rows(FEDERATEDX_IO_RESULT *io_result)
|
||||||
|
{
|
||||||
|
return mysql_num_rows((MYSQL_RES *) io_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FEDERATEDX_IO_ROW *federatedx_io_mysql::fetch_row(FEDERATEDX_IO_RESULT *io_result)
|
||||||
|
{
|
||||||
|
return (FEDERATEDX_IO_ROW *) mysql_fetch_row((MYSQL_RES *) io_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong *federatedx_io_mysql::fetch_lengths(FEDERATEDX_IO_RESULT *io_result)
|
||||||
|
{
|
||||||
|
return mysql_fetch_lengths((MYSQL_RES *) io_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *federatedx_io_mysql::get_column_data(FEDERATEDX_IO_ROW *row,
|
||||||
|
unsigned int column)
|
||||||
|
{
|
||||||
|
return ((MYSQL_ROW)row)[column];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool federatedx_io_mysql::is_column_null(const FEDERATEDX_IO_ROW *row,
|
||||||
|
unsigned int column) const
|
||||||
|
{
|
||||||
|
return !((MYSQL_ROW)row)[column];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool federatedx_io_mysql::table_metadata(ha_statistics *stats,
|
||||||
|
const char *table_name,
|
||||||
|
uint table_name_length, uint flag)
|
||||||
|
{
|
||||||
|
char status_buf[FEDERATEDX_QUERY_BUFFER_SIZE];
|
||||||
|
FEDERATEDX_IO_RESULT *result= 0;
|
||||||
|
FEDERATEDX_IO_ROW *row;
|
||||||
|
String status_query_string(status_buf, sizeof(status_buf), &my_charset_bin);
|
||||||
|
int error;
|
||||||
|
|
||||||
|
status_query_string.length(0);
|
||||||
|
status_query_string.append(STRING_WITH_LEN("SHOW TABLE STATUS LIKE "));
|
||||||
|
append_ident(&status_query_string, table_name,
|
||||||
|
table_name_length, value_quote_char);
|
||||||
|
|
||||||
|
if (query(status_query_string.ptr(), status_query_string.length()))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
status_query_string.length(0);
|
||||||
|
|
||||||
|
result= store_result();
|
||||||
|
|
||||||
|
/*
|
||||||
|
We're going to use fields num. 4, 12 and 13 of the resultset,
|
||||||
|
so make sure we have these fields.
|
||||||
|
*/
|
||||||
|
if (!result || (get_num_fields(result) < 14))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!get_num_rows(result))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!(row= fetch_row(result)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/*
|
||||||
|
deleted is set in ha_federatedx::info
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
need to figure out what this means as far as federatedx is concerned,
|
||||||
|
since we don't have a "file"
|
||||||
|
|
||||||
|
data_file_length = ?
|
||||||
|
index_file_length = ?
|
||||||
|
delete_length = ?
|
||||||
|
*/
|
||||||
|
if (!is_column_null(row, 4))
|
||||||
|
stats->records= (ha_rows) my_strtoll10(get_column_data(row, 4),
|
||||||
|
(char**) 0, &error);
|
||||||
|
if (!is_column_null(row, 5))
|
||||||
|
stats->mean_rec_length= (ulong) my_strtoll10(get_column_data(row, 5),
|
||||||
|
(char**) 0, &error);
|
||||||
|
|
||||||
|
stats->data_file_length= stats->records * stats->mean_rec_length;
|
||||||
|
|
||||||
|
if (!is_column_null(row, 12))
|
||||||
|
stats->update_time= (time_t) my_strtoll10(get_column_data(row, 12),
|
||||||
|
(char**) 0, &error);
|
||||||
|
if (!is_column_null(row, 13))
|
||||||
|
stats->check_time= (time_t) my_strtoll10(get_column_data(row, 13),
|
||||||
|
(char**) 0, &error);
|
||||||
|
|
||||||
|
free_result(result);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
free_result(result);
|
||||||
|
return 1;
|
||||||
|
}
|
277
storage/federatedx/federatedx_io_null.cc
Normal file
277
storage/federatedx/federatedx_io_null.cc
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2007, Antony T Curtis
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Neither the name of FederatedX nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*#define MYSQL_SERVER 1*/
|
||||||
|
#include "mysql_priv.h"
|
||||||
|
#include <mysql/plugin.h>
|
||||||
|
|
||||||
|
#include "ha_federatedx.h"
|
||||||
|
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
|
#pragma implementation // gcc: Class implementation
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define SAVEPOINT_REALIZED 1
|
||||||
|
#define SAVEPOINT_RESTRICT 2
|
||||||
|
#define SAVEPOINT_EMITTED 4
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct federatedx_savepoint
|
||||||
|
{
|
||||||
|
ulong level;
|
||||||
|
uint flags;
|
||||||
|
} SAVEPT;
|
||||||
|
|
||||||
|
|
||||||
|
class federatedx_io_null :public federatedx_io
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
federatedx_io_null(FEDERATEDX_SERVER *);
|
||||||
|
~federatedx_io_null();
|
||||||
|
|
||||||
|
int query(const char *buffer, uint length);
|
||||||
|
virtual FEDERATEDX_IO_RESULT *store_result();
|
||||||
|
|
||||||
|
virtual size_t max_query_size() const;
|
||||||
|
|
||||||
|
virtual my_ulonglong affected_rows() const;
|
||||||
|
virtual my_ulonglong last_insert_id() const;
|
||||||
|
|
||||||
|
virtual int error_code();
|
||||||
|
virtual const char *error_str();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
int commit();
|
||||||
|
int rollback();
|
||||||
|
|
||||||
|
int savepoint_set(ulong sp);
|
||||||
|
ulong savepoint_release(ulong sp);
|
||||||
|
ulong savepoint_rollback(ulong sp);
|
||||||
|
void savepoint_restrict(ulong sp);
|
||||||
|
|
||||||
|
ulong last_savepoint() const;
|
||||||
|
ulong actual_savepoint() const;
|
||||||
|
bool is_autocommit() const;
|
||||||
|
|
||||||
|
bool table_metadata(ha_statistics *stats, const char *table_name,
|
||||||
|
uint table_name_length, uint flag);
|
||||||
|
|
||||||
|
/* resultset operations */
|
||||||
|
|
||||||
|
virtual void free_result(FEDERATEDX_IO_RESULT *io_result);
|
||||||
|
virtual unsigned int get_num_fields(FEDERATEDX_IO_RESULT *io_result);
|
||||||
|
virtual my_ulonglong get_num_rows(FEDERATEDX_IO_RESULT *io_result);
|
||||||
|
virtual FEDERATEDX_IO_ROW *fetch_row(FEDERATEDX_IO_RESULT *io_result);
|
||||||
|
virtual ulong *fetch_lengths(FEDERATEDX_IO_RESULT *io_result);
|
||||||
|
virtual const char *get_column_data(FEDERATEDX_IO_ROW *row,
|
||||||
|
unsigned int column);
|
||||||
|
virtual bool is_column_null(const FEDERATEDX_IO_ROW *row,
|
||||||
|
unsigned int column) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
federatedx_io *instantiate_io_null(MEM_ROOT *server_root,
|
||||||
|
FEDERATEDX_SERVER *server)
|
||||||
|
{
|
||||||
|
return new (server_root) federatedx_io_null(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
federatedx_io_null::federatedx_io_null(FEDERATEDX_SERVER *aserver)
|
||||||
|
: federatedx_io(aserver)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
federatedx_io_null::~federatedx_io_null()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void federatedx_io_null::reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_io_null::commit()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int federatedx_io_null::rollback()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong federatedx_io_null::last_savepoint() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong federatedx_io_null::actual_savepoint() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool federatedx_io_null::is_autocommit() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_io_null::savepoint_set(ulong sp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong federatedx_io_null::savepoint_release(ulong sp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong federatedx_io_null::savepoint_rollback(ulong sp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void federatedx_io_null::savepoint_restrict(ulong sp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_io_null::query(const char *buffer, uint length)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t federatedx_io_null::max_query_size() const
|
||||||
|
{
|
||||||
|
return INT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_ulonglong federatedx_io_null::affected_rows() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_ulonglong federatedx_io_null::last_insert_id() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_io_null::error_code()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *federatedx_io_null::error_str()
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FEDERATEDX_IO_RESULT *federatedx_io_null::store_result()
|
||||||
|
{
|
||||||
|
FEDERATEDX_IO_RESULT *result;
|
||||||
|
DBUG_ENTER("federatedx_io_null::store_result");
|
||||||
|
|
||||||
|
result= NULL;
|
||||||
|
|
||||||
|
DBUG_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void federatedx_io_null::free_result(FEDERATEDX_IO_RESULT *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int federatedx_io_null::get_num_fields(FEDERATEDX_IO_RESULT *)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_ulonglong federatedx_io_null::get_num_rows(FEDERATEDX_IO_RESULT *)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FEDERATEDX_IO_ROW *federatedx_io_null::fetch_row(FEDERATEDX_IO_RESULT *)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong *federatedx_io_null::fetch_lengths(FEDERATEDX_IO_RESULT *)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *federatedx_io_null::get_column_data(FEDERATEDX_IO_ROW *,
|
||||||
|
unsigned int)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool federatedx_io_null::is_column_null(const FEDERATEDX_IO_ROW *,
|
||||||
|
unsigned int) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool federatedx_io_null::table_metadata(ha_statistics *stats,
|
||||||
|
const char *table_name,
|
||||||
|
uint table_name_length, uint flag)
|
||||||
|
{
|
||||||
|
stats->records= (ha_rows) 0;
|
||||||
|
stats->mean_rec_length= (ulong) 0;
|
||||||
|
stats->data_file_length= 0;
|
||||||
|
|
||||||
|
stats->update_time= (time_t) 0;
|
||||||
|
stats->check_time= (time_t) 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
45
storage/federatedx/federatedx_probes.h
Normal file
45
storage/federatedx/federatedx_probes.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Generated by dtrace(1M).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FEDERATED_PROBES_H
|
||||||
|
#define _FEDERATED_PROBES_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _DTRACE_VERSION
|
||||||
|
|
||||||
|
#define FEDERATED_CLOSE() \
|
||||||
|
__dtrace_federated___close()
|
||||||
|
#define FEDERATED_CLOSE_ENABLED() \
|
||||||
|
__dtraceenabled_federated___close()
|
||||||
|
#define FEDERATED_OPEN() \
|
||||||
|
__dtrace_federated___open()
|
||||||
|
#define FEDERATED_OPEN_ENABLED() \
|
||||||
|
__dtraceenabled_federated___open()
|
||||||
|
|
||||||
|
|
||||||
|
extern void __dtrace_federated___close(void);
|
||||||
|
extern int __dtraceenabled_federated___close(void);
|
||||||
|
extern void __dtrace_federated___open(void);
|
||||||
|
extern int __dtraceenabled_federated___open(void);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define FEDERATED_CLOSE()
|
||||||
|
#define FEDERATED_CLOSE_ENABLED() (0)
|
||||||
|
#define FEDERATED_OPEN()
|
||||||
|
#define FEDERATED_OPEN_ENABLED() (0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _FEDERATED_PROBES_H */
|
424
storage/federatedx/federatedx_txn.cc
Normal file
424
storage/federatedx/federatedx_txn.cc
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2007, Antony T Curtis
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Neither the name of FederatedX nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*#define MYSQL_SERVER 1*/
|
||||||
|
#include "mysql_priv.h"
|
||||||
|
#include <mysql/plugin.h>
|
||||||
|
|
||||||
|
#include "ha_federatedx.h"
|
||||||
|
|
||||||
|
#include "m_string.h"
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
|
#pragma implementation // gcc: Class implementation
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
federatedx_txn::federatedx_txn()
|
||||||
|
: txn_list(0), savepoint_level(0), savepoint_stmt(0), savepoint_next(0)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("federatedx_txn::federatedx_txn");
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
federatedx_txn::~federatedx_txn()
|
||||||
|
{
|
||||||
|
DBUG_ENTER("federatedx_txn::~federatedx_txn");
|
||||||
|
DBUG_ASSERT(!txn_list);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void federatedx_txn::close(FEDERATEDX_SERVER *server)
|
||||||
|
{
|
||||||
|
uint count= 0;
|
||||||
|
federatedx_io *io, **iop;
|
||||||
|
DBUG_ENTER("federatedx_txn::close");
|
||||||
|
|
||||||
|
DBUG_ASSERT(!server->use_count);
|
||||||
|
DBUG_PRINT("info",("use count: %u connections: %u",
|
||||||
|
server->use_count, server->io_count));
|
||||||
|
|
||||||
|
for (iop= &txn_list; (io= *iop);)
|
||||||
|
{
|
||||||
|
if (io->server != server)
|
||||||
|
iop= &io->txn_next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*iop= io->txn_next;
|
||||||
|
io->txn_next= NULL;
|
||||||
|
io->busy= FALSE;
|
||||||
|
|
||||||
|
io->idle_next= server->idle_list;
|
||||||
|
server->idle_list= io;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((io= server->idle_list))
|
||||||
|
{
|
||||||
|
server->idle_list= io->idle_next;
|
||||||
|
delete io;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_PRINT("info",("closed %u connections, txn_list: %s", count,
|
||||||
|
txn_list ? "active": "empty"));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_txn::acquire(FEDERATEDX_SHARE *share, bool readonly,
|
||||||
|
federatedx_io **ioptr)
|
||||||
|
{
|
||||||
|
federatedx_io *io;
|
||||||
|
FEDERATEDX_SERVER *server= share->s;
|
||||||
|
DBUG_ENTER("federatedx_txn::acquire");
|
||||||
|
DBUG_ASSERT(ioptr && server);
|
||||||
|
|
||||||
|
if (!(io= *ioptr))
|
||||||
|
{
|
||||||
|
/* check to see if we have an available IO connection */
|
||||||
|
for (io= txn_list; io; io= io->txn_next)
|
||||||
|
if (io->server == server)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!io)
|
||||||
|
{
|
||||||
|
/* check to see if there are any unowned IO connections */
|
||||||
|
pthread_mutex_lock(&server->mutex);
|
||||||
|
if ((io= server->idle_list))
|
||||||
|
{
|
||||||
|
server->idle_list= io->idle_next;
|
||||||
|
io->idle_next= NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
io= federatedx_io::construct(&server->mem_root, server);
|
||||||
|
|
||||||
|
io->txn_next= txn_list;
|
||||||
|
txn_list= io;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&server->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (io->busy)
|
||||||
|
*io->owner_ptr= NULL;
|
||||||
|
|
||||||
|
io->busy= TRUE;
|
||||||
|
io->owner_ptr= ioptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_ASSERT(io->busy && io->server == server);
|
||||||
|
|
||||||
|
io->readonly&= readonly;
|
||||||
|
|
||||||
|
DBUG_RETURN((*ioptr= io) ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void federatedx_txn::release(federatedx_io **ioptr)
|
||||||
|
{
|
||||||
|
federatedx_io *io;
|
||||||
|
DBUG_ENTER("federatedx_txn::release");
|
||||||
|
DBUG_ASSERT(ioptr);
|
||||||
|
|
||||||
|
if ((io= *ioptr))
|
||||||
|
{
|
||||||
|
/* mark as available for reuse in this transaction */
|
||||||
|
io->busy= FALSE;
|
||||||
|
*ioptr= NULL;
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("active: %d autocommit: %d",
|
||||||
|
io->active, io->is_autocommit()));
|
||||||
|
|
||||||
|
if (io->is_autocommit())
|
||||||
|
io->active= FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
release_scan();
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void federatedx_txn::release_scan()
|
||||||
|
{
|
||||||
|
uint count= 0, returned= 0;
|
||||||
|
federatedx_io *io, **pio;
|
||||||
|
DBUG_ENTER("federatedx_txn::release_scan");
|
||||||
|
|
||||||
|
/* return any inactive and idle connections to the server */
|
||||||
|
for (pio= &txn_list; (io= *pio); count++)
|
||||||
|
{
|
||||||
|
if (io->active || io->busy)
|
||||||
|
pio= &io->txn_next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FEDERATEDX_SERVER *server= io->server;
|
||||||
|
|
||||||
|
/* unlink from list of connections bound to the transaction */
|
||||||
|
*pio= io->txn_next;
|
||||||
|
io->txn_next= NULL;
|
||||||
|
|
||||||
|
/* reset some values */
|
||||||
|
io->readonly= TRUE;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&server->mutex);
|
||||||
|
io->idle_next= server->idle_list;
|
||||||
|
server->idle_list= io;
|
||||||
|
pthread_mutex_unlock(&server->mutex);
|
||||||
|
returned++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_PRINT("info",("returned %u of %u connections(s)", returned, count));
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool federatedx_txn::txn_begin()
|
||||||
|
{
|
||||||
|
ulong level= 0;
|
||||||
|
DBUG_ENTER("federatedx_txn::txn_begin");
|
||||||
|
|
||||||
|
if (savepoint_next == 0)
|
||||||
|
{
|
||||||
|
savepoint_next++;
|
||||||
|
savepoint_level= savepoint_stmt= 0;
|
||||||
|
sp_acquire(&level);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(level == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_txn::txn_commit()
|
||||||
|
{
|
||||||
|
int error= 0;
|
||||||
|
federatedx_io *io;
|
||||||
|
DBUG_ENTER("federatedx_txn::txn_commit");
|
||||||
|
|
||||||
|
if (savepoint_next)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(savepoint_stmt != 1);
|
||||||
|
|
||||||
|
for (io= txn_list; io; io= io->txn_next)
|
||||||
|
{
|
||||||
|
int rc= 0;
|
||||||
|
|
||||||
|
if (io->active)
|
||||||
|
rc= io->commit();
|
||||||
|
else
|
||||||
|
io->rollback();
|
||||||
|
|
||||||
|
if (io->active && rc)
|
||||||
|
error= -1;
|
||||||
|
|
||||||
|
io->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
release_scan();
|
||||||
|
|
||||||
|
savepoint_next= savepoint_stmt= savepoint_level= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_txn::txn_rollback()
|
||||||
|
{
|
||||||
|
int error= 0;
|
||||||
|
federatedx_io *io;
|
||||||
|
DBUG_ENTER("federatedx_txn::txn_commit");
|
||||||
|
|
||||||
|
if (savepoint_next)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(savepoint_stmt != 1);
|
||||||
|
|
||||||
|
for (io= txn_list; io; io= io->txn_next)
|
||||||
|
{
|
||||||
|
int rc= io->rollback();
|
||||||
|
|
||||||
|
if (io->active && rc)
|
||||||
|
error= -1;
|
||||||
|
|
||||||
|
io->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
release_scan();
|
||||||
|
|
||||||
|
savepoint_next= savepoint_stmt= savepoint_level= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool federatedx_txn::sp_acquire(ulong *sp)
|
||||||
|
{
|
||||||
|
bool rc= FALSE;
|
||||||
|
federatedx_io *io;
|
||||||
|
DBUG_ENTER("federatedx_txn::sp_acquire");
|
||||||
|
DBUG_ASSERT(sp && savepoint_next);
|
||||||
|
|
||||||
|
*sp= savepoint_level= savepoint_next++;
|
||||||
|
|
||||||
|
for (io= txn_list; io; io= io->txn_next)
|
||||||
|
{
|
||||||
|
if (io->readonly)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
io->savepoint_set(savepoint_level);
|
||||||
|
rc= TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_txn::sp_rollback(ulong *sp)
|
||||||
|
{
|
||||||
|
ulong level, new_level= savepoint_level;
|
||||||
|
federatedx_io *io;
|
||||||
|
DBUG_ENTER("federatedx_txn::sp_rollback");
|
||||||
|
DBUG_ASSERT(sp && savepoint_next && *sp && *sp <= savepoint_level);
|
||||||
|
|
||||||
|
for (io= txn_list; io; io= io->txn_next)
|
||||||
|
{
|
||||||
|
if (io->readonly)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((level= io->savepoint_rollback(*sp)) < new_level)
|
||||||
|
new_level= level;
|
||||||
|
}
|
||||||
|
|
||||||
|
savepoint_level= new_level;
|
||||||
|
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_txn::sp_release(ulong *sp)
|
||||||
|
{
|
||||||
|
ulong level, new_level= savepoint_level;
|
||||||
|
federatedx_io *io;
|
||||||
|
DBUG_ENTER("federatedx_txn::sp_release");
|
||||||
|
DBUG_ASSERT(sp && savepoint_next && *sp && *sp <= savepoint_level);
|
||||||
|
|
||||||
|
for (io= txn_list; io; io= io->txn_next)
|
||||||
|
{
|
||||||
|
if (io->readonly)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((level= io->savepoint_release(*sp)) < new_level)
|
||||||
|
new_level= level;
|
||||||
|
}
|
||||||
|
|
||||||
|
savepoint_level= new_level;
|
||||||
|
*sp= 0;
|
||||||
|
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool federatedx_txn::stmt_begin()
|
||||||
|
{
|
||||||
|
bool result= FALSE;
|
||||||
|
DBUG_ENTER("federatedx_txn::stmt_begin");
|
||||||
|
|
||||||
|
if (!savepoint_stmt)
|
||||||
|
{
|
||||||
|
if (!savepoint_next)
|
||||||
|
{
|
||||||
|
savepoint_next++;
|
||||||
|
savepoint_level= savepoint_stmt= 0;
|
||||||
|
}
|
||||||
|
result= sp_acquire(&savepoint_stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_txn::stmt_commit()
|
||||||
|
{
|
||||||
|
int result= 0;
|
||||||
|
DBUG_ENTER("federatedx_txn::stmt_commit");
|
||||||
|
|
||||||
|
if (savepoint_stmt == 1)
|
||||||
|
{
|
||||||
|
savepoint_stmt= 0;
|
||||||
|
result= txn_commit();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (savepoint_stmt)
|
||||||
|
result= sp_release(&savepoint_stmt);
|
||||||
|
|
||||||
|
DBUG_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int federatedx_txn::stmt_rollback()
|
||||||
|
{
|
||||||
|
int result= 0;
|
||||||
|
DBUG_ENTER("federated:txn::stmt_rollback");
|
||||||
|
|
||||||
|
if (savepoint_stmt == 1)
|
||||||
|
{
|
||||||
|
savepoint_stmt= 0;
|
||||||
|
result= txn_rollback();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (savepoint_stmt)
|
||||||
|
{
|
||||||
|
result= sp_rollback(&savepoint_stmt);
|
||||||
|
sp_release(&savepoint_stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void federatedx_txn::stmt_autocommit()
|
||||||
|
{
|
||||||
|
federatedx_io *io;
|
||||||
|
DBUG_ENTER("federatedx_txn::stmt_autocommit");
|
||||||
|
|
||||||
|
for (io= txn_list; savepoint_stmt && io; io= io->txn_next)
|
||||||
|
{
|
||||||
|
if (io->readonly)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
io->savepoint_restrict(savepoint_stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
3487
storage/federatedx/ha_federatedx.cc
Normal file
3487
storage/federatedx/ha_federatedx.cc
Normal file
File diff suppressed because it is too large
Load Diff
446
storage/federatedx/ha_federatedx.h
Normal file
446
storage/federatedx/ha_federatedx.h
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008, Patrick Galbraith
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
* Neither the name of Patrick Galbraith nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class federatedx_io;
|
||||||
|
|
||||||
|
/*
|
||||||
|
FEDERATEDX_SERVER will eventually be a structure that will be shared among
|
||||||
|
all FEDERATEDX_SHARE instances so that the federated server can minimise
|
||||||
|
the number of open connections. This will eventually lead to the support
|
||||||
|
of reliable XA federated tables.
|
||||||
|
*/
|
||||||
|
typedef struct st_fedrated_server {
|
||||||
|
MEM_ROOT mem_root;
|
||||||
|
uint use_count, io_count;
|
||||||
|
|
||||||
|
uchar *key;
|
||||||
|
uint key_length;
|
||||||
|
|
||||||
|
const char *scheme;
|
||||||
|
const char *hostname;
|
||||||
|
const char *username;
|
||||||
|
const char *password;
|
||||||
|
const char *database;
|
||||||
|
const char *socket;
|
||||||
|
ushort port;
|
||||||
|
|
||||||
|
const char *csname;
|
||||||
|
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
federatedx_io *idle_list;
|
||||||
|
} FEDERATEDX_SERVER;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Please read ha_exmple.cc before reading this file.
|
||||||
|
Please keep in mind that the federatedx storage engine implements all methods
|
||||||
|
that are required to be implemented. handler.h has a full list of methods
|
||||||
|
that you can implement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMA_INTERFACE
|
||||||
|
#pragma interface /* gcc class implementation */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <mysql.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
handler::print_error has a case statement for error numbers.
|
||||||
|
This value is (10000) is far out of range and will envoke the
|
||||||
|
default: case.
|
||||||
|
(Current error range is 120-159 from include/my_base.h)
|
||||||
|
*/
|
||||||
|
#define HA_FEDERATEDX_ERROR_WITH_REMOTE_SYSTEM 10000
|
||||||
|
|
||||||
|
#define FEDERATEDX_QUERY_BUFFER_SIZE STRING_BUFFER_USUAL_SIZE * 5
|
||||||
|
#define FEDERATEDX_RECORDS_IN_RANGE 2
|
||||||
|
#define FEDERATEDX_MAX_KEY_LENGTH 3500 // Same as innodb
|
||||||
|
|
||||||
|
/*
|
||||||
|
FEDERATEDX_SHARE is a structure that will be shared amoung all open handlers
|
||||||
|
The example implements the minimum of what you will probably need.
|
||||||
|
*/
|
||||||
|
typedef struct st_federatedx_share {
|
||||||
|
MEM_ROOT mem_root;
|
||||||
|
|
||||||
|
bool parsed;
|
||||||
|
/* this key is unique db/tablename */
|
||||||
|
const char *share_key;
|
||||||
|
/*
|
||||||
|
the primary select query to be used in rnd_init
|
||||||
|
*/
|
||||||
|
char *select_query;
|
||||||
|
/*
|
||||||
|
remote host info, parse_url supplies
|
||||||
|
*/
|
||||||
|
char *server_name;
|
||||||
|
char *connection_string;
|
||||||
|
char *scheme;
|
||||||
|
char *hostname;
|
||||||
|
char *username;
|
||||||
|
char *password;
|
||||||
|
char *database;
|
||||||
|
char *table_name;
|
||||||
|
char *table;
|
||||||
|
char *socket;
|
||||||
|
char *sport;
|
||||||
|
int share_key_length;
|
||||||
|
ushort port;
|
||||||
|
|
||||||
|
uint table_name_length, server_name_length, connect_string_length;
|
||||||
|
uint use_count;
|
||||||
|
THR_LOCK lock;
|
||||||
|
FEDERATEDX_SERVER *s;
|
||||||
|
} FEDERATEDX_SHARE;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct st_federatedx_result FEDERATEDX_IO_RESULT;
|
||||||
|
typedef struct st_federatedx_row FEDERATEDX_IO_ROW;
|
||||||
|
typedef ptrdiff_t FEDERATEDX_IO_OFFSET;
|
||||||
|
|
||||||
|
class federatedx_io
|
||||||
|
{
|
||||||
|
friend class federatedx_txn;
|
||||||
|
FEDERATEDX_SERVER * const server;
|
||||||
|
federatedx_io **owner_ptr;
|
||||||
|
federatedx_io *txn_next;
|
||||||
|
federatedx_io *idle_next;
|
||||||
|
bool active; /* currently participating in a transaction */
|
||||||
|
bool busy; /* in use by a ha_federated instance */
|
||||||
|
bool readonly;/* indicates that no updates have occurred */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void set_active(bool new_active)
|
||||||
|
{ active= new_active; }
|
||||||
|
public:
|
||||||
|
federatedx_io(FEDERATEDX_SERVER *);
|
||||||
|
virtual ~federatedx_io();
|
||||||
|
|
||||||
|
bool is_readonly() const { return readonly; }
|
||||||
|
bool is_active() const { return active; }
|
||||||
|
|
||||||
|
const char * get_charsetname() const
|
||||||
|
{ return server->csname ? server->csname : "latin1"; }
|
||||||
|
|
||||||
|
const char * get_hostname() const { return server->hostname; }
|
||||||
|
const char * get_username() const { return server->username; }
|
||||||
|
const char * get_password() const { return server->password; }
|
||||||
|
const char * get_database() const { return server->database; }
|
||||||
|
ushort get_port() const { return server->port; }
|
||||||
|
const char * get_socket() const { return server->socket; }
|
||||||
|
|
||||||
|
static bool handles_scheme(const char *scheme);
|
||||||
|
static federatedx_io *construct(MEM_ROOT *server_root,
|
||||||
|
FEDERATEDX_SERVER *server);
|
||||||
|
|
||||||
|
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
|
||||||
|
{ return alloc_root(mem_root, size); }
|
||||||
|
static void operator delete(void *ptr, size_t size)
|
||||||
|
{ TRASH(ptr, size); }
|
||||||
|
|
||||||
|
virtual int query(const char *buffer, uint length)=0;
|
||||||
|
virtual FEDERATEDX_IO_RESULT *store_result()=0;
|
||||||
|
|
||||||
|
virtual size_t max_query_size() const=0;
|
||||||
|
|
||||||
|
virtual my_ulonglong affected_rows() const=0;
|
||||||
|
virtual my_ulonglong last_insert_id() const=0;
|
||||||
|
|
||||||
|
virtual int error_code()=0;
|
||||||
|
virtual const char *error_str()=0;
|
||||||
|
|
||||||
|
virtual void reset()=0;
|
||||||
|
virtual int commit()=0;
|
||||||
|
virtual int rollback()=0;
|
||||||
|
|
||||||
|
virtual int savepoint_set(ulong sp)=0;
|
||||||
|
virtual ulong savepoint_release(ulong sp)=0;
|
||||||
|
virtual ulong savepoint_rollback(ulong sp)=0;
|
||||||
|
virtual void savepoint_restrict(ulong sp)=0;
|
||||||
|
|
||||||
|
virtual ulong last_savepoint() const=0;
|
||||||
|
virtual ulong actual_savepoint() const=0;
|
||||||
|
virtual bool is_autocommit() const=0;
|
||||||
|
|
||||||
|
virtual bool table_metadata(ha_statistics *stats, const char *table_name,
|
||||||
|
uint table_name_length, uint flag) = 0;
|
||||||
|
|
||||||
|
/* resultset operations */
|
||||||
|
|
||||||
|
virtual void free_result(FEDERATEDX_IO_RESULT *io_result)=0;
|
||||||
|
virtual unsigned int get_num_fields(FEDERATEDX_IO_RESULT *io_result)=0;
|
||||||
|
virtual my_ulonglong get_num_rows(FEDERATEDX_IO_RESULT *io_result)=0;
|
||||||
|
virtual FEDERATEDX_IO_ROW *fetch_row(FEDERATEDX_IO_RESULT *io_result)=0;
|
||||||
|
virtual ulong *fetch_lengths(FEDERATEDX_IO_RESULT *io_result)=0;
|
||||||
|
virtual const char *get_column_data(FEDERATEDX_IO_ROW *row,
|
||||||
|
unsigned int column)=0;
|
||||||
|
virtual bool is_column_null(const FEDERATEDX_IO_ROW *row,
|
||||||
|
unsigned int column) const=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class federatedx_txn
|
||||||
|
{
|
||||||
|
federatedx_io *txn_list;
|
||||||
|
ulong savepoint_level;
|
||||||
|
ulong savepoint_stmt;
|
||||||
|
ulong savepoint_next;
|
||||||
|
|
||||||
|
void release_scan();
|
||||||
|
public:
|
||||||
|
federatedx_txn();
|
||||||
|
~federatedx_txn();
|
||||||
|
|
||||||
|
bool has_connections() const { return txn_list != NULL; }
|
||||||
|
bool in_transaction() const { return savepoint_next != 0; }
|
||||||
|
int acquire(FEDERATEDX_SHARE *share, bool readonly, federatedx_io **io);
|
||||||
|
void release(federatedx_io **io);
|
||||||
|
void close(FEDERATEDX_SERVER *);
|
||||||
|
|
||||||
|
bool txn_begin();
|
||||||
|
int txn_commit();
|
||||||
|
int txn_rollback();
|
||||||
|
|
||||||
|
bool sp_acquire(ulong *save);
|
||||||
|
int sp_rollback(ulong *save);
|
||||||
|
int sp_release(ulong *save);
|
||||||
|
|
||||||
|
bool stmt_begin();
|
||||||
|
int stmt_commit();
|
||||||
|
int stmt_rollback();
|
||||||
|
void stmt_autocommit();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class definition for the storage engine
|
||||||
|
*/
|
||||||
|
class ha_federatedx: public handler
|
||||||
|
{
|
||||||
|
friend int federatedx_db_init(void *p);
|
||||||
|
|
||||||
|
THR_LOCK_DATA lock; /* MySQL lock */
|
||||||
|
FEDERATEDX_SHARE *share; /* Shared lock info */
|
||||||
|
federatedx_txn *txn;
|
||||||
|
federatedx_io *io;
|
||||||
|
FEDERATEDX_IO_RESULT *stored_result;
|
||||||
|
uint fetch_num; // stores the fetch num
|
||||||
|
FEDERATEDX_IO_OFFSET current_position; // Current position used by ::position()
|
||||||
|
int remote_error_number;
|
||||||
|
char remote_error_buf[FEDERATEDX_QUERY_BUFFER_SIZE];
|
||||||
|
bool ignore_duplicates, replace_duplicates;
|
||||||
|
bool insert_dup_update;
|
||||||
|
DYNAMIC_STRING bulk_insert;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
return 0 on success
|
||||||
|
return errorcode otherwise
|
||||||
|
*/
|
||||||
|
uint convert_row_to_internal_format(uchar *buf, FEDERATEDX_IO_ROW *row,
|
||||||
|
FEDERATEDX_IO_RESULT *result);
|
||||||
|
bool create_where_from_key(String *to, KEY *key_info,
|
||||||
|
const key_range *start_key,
|
||||||
|
const key_range *end_key,
|
||||||
|
bool records_in_range, bool eq_range);
|
||||||
|
int stash_remote_error();
|
||||||
|
|
||||||
|
federatedx_txn *get_txn(THD *thd, bool no_create= FALSE);
|
||||||
|
|
||||||
|
static int disconnect(handlerton *hton, MYSQL_THD thd);
|
||||||
|
static int savepoint_set(handlerton *hton, MYSQL_THD thd, void *sv);
|
||||||
|
static int savepoint_rollback(handlerton *hton, MYSQL_THD thd, void *sv);
|
||||||
|
static int savepoint_release(handlerton *hton, MYSQL_THD thd, void *sv);
|
||||||
|
static int commit(handlerton *hton, MYSQL_THD thd, bool all);
|
||||||
|
static int rollback(handlerton *hton, MYSQL_THD thd, bool all);
|
||||||
|
|
||||||
|
bool append_stmt_insert(String *query);
|
||||||
|
|
||||||
|
int read_next(uchar *buf, FEDERATEDX_IO_RESULT *result);
|
||||||
|
int index_read_idx_with_result_set(uchar *buf, uint index,
|
||||||
|
const uchar *key,
|
||||||
|
uint key_len,
|
||||||
|
ha_rkey_function find_flag,
|
||||||
|
FEDERATEDX_IO_RESULT **result);
|
||||||
|
int real_query(const char *query, uint length);
|
||||||
|
int real_connect(FEDERATEDX_SHARE *my_share, uint create_flag);
|
||||||
|
public:
|
||||||
|
ha_federatedx(handlerton *hton, TABLE_SHARE *table_arg);
|
||||||
|
~ha_federatedx() {}
|
||||||
|
/* The name that will be used for display purposes */
|
||||||
|
const char *table_type() const { return "FEDERATED"; }
|
||||||
|
/*
|
||||||
|
The name of the index type that will be used for display
|
||||||
|
don't implement this method unless you really have indexes
|
||||||
|
*/
|
||||||
|
// perhaps get index type
|
||||||
|
const char *index_type(uint inx) { return "REMOTE"; }
|
||||||
|
const char **bas_ext() const;
|
||||||
|
/*
|
||||||
|
This is a list of flags that says what the storage engine
|
||||||
|
implements. The current table flags are documented in
|
||||||
|
handler.h
|
||||||
|
*/
|
||||||
|
ulonglong table_flags() const
|
||||||
|
{
|
||||||
|
/* fix server to be able to get remote server table flags */
|
||||||
|
return (HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED
|
||||||
|
| HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS |
|
||||||
|
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
||||||
|
HA_NO_PREFIX_CHAR_KEYS | HA_PRIMARY_KEY_REQUIRED_FOR_DELETE |
|
||||||
|
HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
This is a bitmap of flags that says how the storage engine
|
||||||
|
implements indexes. The current index flags are documented in
|
||||||
|
handler.h. If you do not implement indexes, just return zero
|
||||||
|
here.
|
||||||
|
|
||||||
|
part is the key part to check. First key part is 0
|
||||||
|
If all_parts it's set, MySQL want to know the flags for the combined
|
||||||
|
index up to and including 'part'.
|
||||||
|
*/
|
||||||
|
/* fix server to be able to get remote server index flags */
|
||||||
|
ulong index_flags(uint inx, uint part, bool all_parts) const
|
||||||
|
{
|
||||||
|
return (HA_READ_NEXT | HA_READ_RANGE | HA_READ_AFTER_KEY);
|
||||||
|
}
|
||||||
|
uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
|
||||||
|
uint max_supported_keys() const { return MAX_KEY; }
|
||||||
|
uint max_supported_key_parts() const { return MAX_REF_PARTS; }
|
||||||
|
uint max_supported_key_length() const { return FEDERATEDX_MAX_KEY_LENGTH; }
|
||||||
|
uint max_supported_key_part_length() const { return FEDERATEDX_MAX_KEY_LENGTH; }
|
||||||
|
/*
|
||||||
|
Called in test_quick_select to determine if indexes should be used.
|
||||||
|
Normally, we need to know number of blocks . For federatedx we need to
|
||||||
|
know number of blocks on remote side, and number of packets and blocks
|
||||||
|
on the network side (?)
|
||||||
|
Talk to Kostja about this - how to get the
|
||||||
|
number of rows * ...
|
||||||
|
disk scan time on other side (block size, size of the row) + network time ...
|
||||||
|
The reason for "records * 1000" is that such a large number forces
|
||||||
|
this to use indexes "
|
||||||
|
*/
|
||||||
|
double scan_time()
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info", ("records %lu", (ulong) stats.records));
|
||||||
|
return (double)(stats.records*1000);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
The next method will never be called if you do not implement indexes.
|
||||||
|
*/
|
||||||
|
double read_time(uint index, uint ranges, ha_rows rows)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Per Brian, this number is bugus, but this method must be implemented,
|
||||||
|
and at a later date, he intends to document this issue for handler code
|
||||||
|
*/
|
||||||
|
return (double) rows / 20.0+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const key_map *keys_to_use_for_scanning() { return &key_map_full; }
|
||||||
|
/*
|
||||||
|
Everything below are methods that we implment in ha_federatedx.cc.
|
||||||
|
|
||||||
|
Most of these methods are not obligatory, skip them and
|
||||||
|
MySQL will treat them as not implemented
|
||||||
|
*/
|
||||||
|
int open(const char *name, int mode, uint test_if_locked); // required
|
||||||
|
int close(void); // required
|
||||||
|
|
||||||
|
void start_bulk_insert(ha_rows rows);
|
||||||
|
int end_bulk_insert(bool abort);
|
||||||
|
int write_row(uchar *buf);
|
||||||
|
int update_row(const uchar *old_data, uchar *new_data);
|
||||||
|
int delete_row(const uchar *buf);
|
||||||
|
int index_init(uint keynr, bool sorted);
|
||||||
|
ha_rows estimate_rows_upper_bound();
|
||||||
|
int index_read(uchar *buf, const uchar *key,
|
||||||
|
uint key_len, enum ha_rkey_function find_flag);
|
||||||
|
int index_read_idx(uchar *buf, uint idx, const uchar *key,
|
||||||
|
uint key_len, enum ha_rkey_function find_flag);
|
||||||
|
int index_next(uchar *buf);
|
||||||
|
int index_end();
|
||||||
|
int read_range_first(const key_range *start_key,
|
||||||
|
const key_range *end_key,
|
||||||
|
bool eq_range, bool sorted);
|
||||||
|
int read_range_next();
|
||||||
|
/*
|
||||||
|
unlike index_init(), rnd_init() can be called two times
|
||||||
|
without rnd_end() in between (it only makes sense if scan=1).
|
||||||
|
then the second call should prepare for the new table scan
|
||||||
|
(e.g if rnd_init allocates the cursor, second call should
|
||||||
|
position it to the start of the table, no need to deallocate
|
||||||
|
and allocate it again
|
||||||
|
*/
|
||||||
|
int rnd_init(bool scan); //required
|
||||||
|
int rnd_end();
|
||||||
|
int rnd_next(uchar *buf); //required
|
||||||
|
int rnd_pos(uchar *buf, uchar *pos); //required
|
||||||
|
void position(const uchar *record); //required
|
||||||
|
int info(uint); //required
|
||||||
|
int extra(ha_extra_function operation);
|
||||||
|
|
||||||
|
void update_auto_increment(void);
|
||||||
|
int repair(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
|
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
|
|
||||||
|
int delete_all_rows(void);
|
||||||
|
int create(const char *name, TABLE *form,
|
||||||
|
HA_CREATE_INFO *create_info); //required
|
||||||
|
ha_rows records_in_range(uint inx, key_range *start_key,
|
||||||
|
key_range *end_key);
|
||||||
|
uint8 table_cache_type() { return HA_CACHE_TBL_NOCACHE; }
|
||||||
|
|
||||||
|
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
|
||||||
|
enum thr_lock_type lock_type); //required
|
||||||
|
bool get_error_message(int error, String *buf);
|
||||||
|
int start_stmt(THD *thd, thr_lock_type lock_type);
|
||||||
|
int external_lock(THD *thd, int lock_type);
|
||||||
|
int reset(void);
|
||||||
|
int free_result(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const char ident_quote_char; // Character for quoting
|
||||||
|
// identifiers
|
||||||
|
extern const char value_quote_char; // Character for quoting
|
||||||
|
// literals
|
||||||
|
|
||||||
|
extern bool append_ident(String *string, const char *name, uint length,
|
||||||
|
const char quote_char);
|
||||||
|
|
||||||
|
|
||||||
|
extern federatedx_io *instantiate_io_mysql(MEM_ROOT *server_root,
|
||||||
|
FEDERATEDX_SERVER *server);
|
||||||
|
extern federatedx_io *instantiate_io_null(MEM_ROOT *server_root,
|
||||||
|
FEDERATEDX_SERVER *server);
|
5
storage/federatedx/plug.in
Normal file
5
storage/federatedx/plug.in
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
MYSQL_STORAGE_ENGINE(federated,,[FederatedX Storage Engine],
|
||||||
|
[FederatedX Storage Engine], [max,max-no-ndb])
|
||||||
|
MYSQL_PLUGIN_DYNAMIC(federated, [ha_federatedx.la])
|
||||||
|
MYSQL_PLUGIN_STATIC(federated, [libfederatedx.a])
|
||||||
|
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(federated, [ha_federatedx.cc])
|
@ -374,7 +374,7 @@ xtPublic void xt_ind_release_handle(XTIndHandlePtr handle, xtBool have_lock, XTT
|
|||||||
{
|
{
|
||||||
DcHandleSlotPtr hs;
|
DcHandleSlotPtr hs;
|
||||||
XTIndBlockPtr block = NULL;
|
XTIndBlockPtr block = NULL;
|
||||||
u_int hash_idx = NULL;
|
u_int hash_idx = 0;
|
||||||
DcSegmentPtr seg = NULL;
|
DcSegmentPtr seg = NULL;
|
||||||
XTIndBlockPtr xblock;
|
XTIndBlockPtr xblock;
|
||||||
|
|
||||||
@ -1379,7 +1379,7 @@ xtPublic xtBool xt_ind_fetch(XTOpenTablePtr ot, XTIndexPtr ind, xtIndexNodeID ad
|
|||||||
ASSERT_NS(iref->ir_xlock == 2);
|
ASSERT_NS(iref->ir_xlock == 2);
|
||||||
#endif
|
#endif
|
||||||
if (!(block = ind_cac_fetch(ot, ind, address, &seg, TRUE)))
|
if (!(block = ind_cac_fetch(ot, ind, address, &seg, TRUE)))
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
branch_size = XT_GET_DISK_2(((XTIdxBranchDPtr) block->cb_data)->tb_size_2);
|
branch_size = XT_GET_DISK_2(((XTIdxBranchDPtr) block->cb_data)->tb_size_2);
|
||||||
if (XT_GET_INDEX_BLOCK_LEN(branch_size) < 2 || XT_GET_INDEX_BLOCK_LEN(branch_size) > XT_INDEX_PAGE_SIZE) {
|
if (XT_GET_INDEX_BLOCK_LEN(branch_size) < 2 || XT_GET_INDEX_BLOCK_LEN(branch_size) > XT_INDEX_PAGE_SIZE) {
|
||||||
|
@ -1056,7 +1056,7 @@ buf_page_release(
|
|||||||
buf_block_t* block, /* in: buffer block */
|
buf_block_t* block, /* in: buffer block */
|
||||||
ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH,
|
ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH,
|
||||||
RW_NO_LATCH */
|
RW_NO_LATCH */
|
||||||
mtr_t* mtr) /* in: mtr */
|
mtr_t* mtr __attribute__((unused))) /* in: mtr */
|
||||||
{
|
{
|
||||||
ut_ad(block);
|
ut_ad(block);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user