Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
69bf342a
Commit
69bf342a
authored
Jul 10, 2006
by
ingo/mydev@chilla.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge chilla.local:/home/mydev/mysql-5.1-amerge
into chilla.local:/home/mydev/mysql-5.1-aid
parents
4cdb1469
99a2489e
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
335 additions
and
194 deletions
+335
-194
mysql-test/r/federated.result
mysql-test/r/federated.result
+88
-1
mysql-test/t/federated.test
mysql-test/t/federated.test
+18
-14
sql/ha_federated.cc
sql/ha_federated.cc
+218
-176
sql/ha_federated.h
sql/ha_federated.h
+11
-3
No files found.
mysql-test/r/federated.result
View file @
69bf342a
...
@@ -1558,6 +1558,8 @@ id
...
@@ -1558,6 +1558,8 @@ id
3
3
4
4
5
5
DROP TABLE federated.t1;
DROP TABLE federated.t1;
DROP TABLE IF EXISTS federated.bug_17377_table;
DROP TABLE IF EXISTS federated.bug_17377_table;
CREATE TABLE federated.bug_17377_table (
CREATE TABLE federated.bug_17377_table (
`fld_cid` bigint(20) NOT NULL auto_increment,
`fld_cid` bigint(20) NOT NULL auto_increment,
...
@@ -1601,7 +1603,92 @@ fld_cid fld_name fld_parentid fld_delt
...
@@ -1601,7 +1603,92 @@ fld_cid fld_name fld_parentid fld_delt
5 Torkel 0 0
5 Torkel 0 0
DROP TABLE federated.t1;
DROP TABLE federated.t1;
DROP TABLE federated.bug_17377_table;
DROP TABLE federated.bug_17377_table;
DROP TABLE federated.t1;
create table federated.t1 (i1 int, i2 int, i3 int);
create table federated.t2 (id int, c1 varchar(20), c2 varchar(20));
create table federated.t1 (i1 int, i2 int, i3 int) ENGINE=FEDERATED CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
create table federated.t2 (id int, c1 varchar(20), c2 varchar(20)) ENGINE=FEDERATED CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t2';
insert into federated.t1 values (1,5,10),(3,7,12),(4,5,2),(9,10,15),(2,2,2);
insert into federated.t2 values (9,"abc","def"),(5,"opq","lmn"),(2,"test t","t test");
select * from federated.t1 order by i1;
i1 i2 i3
1 5 10
2 2 2
3 7 12
4 5 2
9 10 15
select * from federated.t2;
id c1 c2
9 abc def
5 opq lmn
2 test t t test
update federated.t1,federated.t2 set t1.i2=15, t2.c2="ppc" where t1.i1=t2.id;
select * from federated.t1 order by i1;
i1 i2 i3
1 5 10
2 15 2
3 7 12
4 5 2
9 15 15
select * from federated.t2 order by id;
id c1 c2
2 test t ppc
5 opq lmn
9 abc ppc
delete federated.t1.*,federated.t2.* from federated.t1,federated.t2 where t1.i2=t2.id;
select * from federated.t1 order by i1;
i1 i2 i3
2 15 2
3 7 12
9 15 15
select * from federated.t2 order by id;
id c1 c2
2 test t ppc
9 abc ppc
drop table federated.t1, federated.t2;
drop table federated.t1, federated.t2;
create table federated.t1 (i1 int, i2 int, i3 int, primary key (i1));
create table federated.t2 (id int, c1 varchar(20), c2 varchar(20), primary key (id));
create table federated.t1 (i1 int auto_increment not null, i2 int, i3 int, primary key (i1)) ENGINE=FEDERATED CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
create table federated.t2 (id int auto_increment not null, c1 varchar(20), c2 varchar(20), primary key(id)) ENGINE=FEDERATED CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t2';
insert into federated.t1 values (1,5,10),(3,7,12),(4,5,2),(9,10,15),(2,2,2);
insert into federated.t2 values (9,"abc","def"),(5,"opq","lmn"),(2,"test t","t test");
select * from federated.t1 order by i1;
i1 i2 i3
1 5 10
2 2 2
3 7 12
4 5 2
9 10 15
select * from federated.t2 order by id;
id c1 c2
2 test t t test
5 opq lmn
9 abc def
update federated.t1,federated.t2 set t1.i2=15, t2.c2="ppc" where t1.i1=t2.id;
select * from federated.t1 order by i1;
i1 i2 i3
1 5 10
2 15 2
3 7 12
4 5 2
9 15 15
select * from federated.t2 order by id;
id c1 c2
2 test t ppc
5 opq lmn
9 abc ppc
delete federated.t1.*,federated.t2.* from federated.t1,federated.t2 where t1.i2=t2.id;
select * from federated.t1 order by i1;
i1 i2 i3
2 15 2
3 7 12
9 15 15
select * from federated.t2 order by id;
id c1 c2
2 test t ppc
9 abc ppc
drop table federated.t1, federated.t2;
drop table federated.t1, federated.t2;
DROP TABLE IF EXISTS federated.t1;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1;
DROP TABLE IF EXISTS federated.t1;
...
...
mysql-test/t/federated.test
View file @
69bf342a
...
@@ -1256,6 +1256,10 @@ SELECT LAST_INSERT_ID();
...
@@ -1256,6 +1256,10 @@ SELECT LAST_INSERT_ID();
INSERT
INTO
federated
.
t1
VALUES
();
INSERT
INTO
federated
.
t1
VALUES
();
SELECT
LAST_INSERT_ID
();
SELECT
LAST_INSERT_ID
();
SELECT
*
FROM
federated
.
t1
;
SELECT
*
FROM
federated
.
t1
;
DROP
TABLE
federated
.
t1
;
connection
slave
;
DROP
TABLE
federated
.
t1
;
#
#
# Bug#17377 Federated Engine returns wrong Data, always the rows
# Bug#17377 Federated Engine returns wrong Data, always the rows
...
@@ -1310,19 +1314,19 @@ select * from federated.t1 where fld_parentid=0 and fld_delt=0;
...
@@ -1310,19 +1314,19 @@ select * from federated.t1 where fld_parentid=0 and fld_delt=0;
DROP
TABLE
federated
.
t1
;
DROP
TABLE
federated
.
t1
;
connection
slave
;
connection
slave
;
DROP
TABLE
federated
.
bug_17377_table
;
DROP
TABLE
federated
.
bug_17377_table
;
DROP
TABLE
federated
.
t1
;
#
#
# Test multi updates and deletes without keys
# BUG 19773 Crash when using multi-table updates, deletes
# with federated tables
#
#
# The following can be enabled when bug #19773 has been fixed
--
disable_parsing
connection
slave
;
connection
slave
;
create
table
federated
.
t1
(
i1
int
,
i2
int
,
i3
int
);
create
table
federated
.
t1
(
i1
int
,
i2
int
,
i3
int
);
create
table
federated
.
t2
(
id
int
,
c1
varchar
(
20
),
c2
varchar
(
20
));
create
table
federated
.
t2
(
id
int
,
c1
varchar
(
20
),
c2
varchar
(
20
));
connection
master
;
connection
master
;
--
replace_result
$SLAVE_MYPORT
SLAVE_PORT
eval
create
table
federated
.
t1
(
i1
int
,
i2
int
,
i3
int
)
ENGINE
=
FEDERATED
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'
;
eval
create
table
federated
.
t1
(
i1
int
,
i2
int
,
i3
int
)
ENGINE
=
FEDERATED
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'
;
--
replace_result
$SLAVE_MYPORT
SLAVE_PORT
eval
create
table
federated
.
t2
(
id
int
,
c1
varchar
(
20
),
c2
varchar
(
20
))
ENGINE
=
FEDERATED
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t2'
;
eval
create
table
federated
.
t2
(
id
int
,
c1
varchar
(
20
),
c2
varchar
(
20
))
ENGINE
=
FEDERATED
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t2'
;
insert
into
federated
.
t1
values
(
1
,
5
,
10
),(
3
,
7
,
12
),(
4
,
5
,
2
),(
9
,
10
,
15
),(
2
,
2
,
2
);
insert
into
federated
.
t1
values
(
1
,
5
,
10
),(
3
,
7
,
12
),(
4
,
5
,
2
),(
9
,
10
,
15
),(
2
,
2
,
2
);
insert
into
federated
.
t2
values
(
9
,
"abc"
,
"def"
),(
5
,
"opq"
,
"lmn"
),(
2
,
"test t"
,
"t test"
);
insert
into
federated
.
t2
values
(
9
,
"abc"
,
"def"
),(
5
,
"opq"
,
"lmn"
),(
2
,
"test t"
,
"t test"
);
...
@@ -1331,22 +1335,23 @@ select * from federated.t2;
...
@@ -1331,22 +1335,23 @@ select * from federated.t2;
update
federated
.
t1
,
federated
.
t2
set
t1
.
i2
=
15
,
t2
.
c2
=
"ppc"
where
t1
.
i1
=
t2
.
id
;
update
federated
.
t1
,
federated
.
t2
set
t1
.
i2
=
15
,
t2
.
c2
=
"ppc"
where
t1
.
i1
=
t2
.
id
;
select
*
from
federated
.
t1
order
by
i1
;
select
*
from
federated
.
t1
order
by
i1
;
select
*
from
federated
.
t2
order
by
id
;
select
*
from
federated
.
t2
order
by
id
;
delete
t1
.*
,
t2
.*
from
federated
.
t1
,
federated
.
t2
where
t1
.
i2
=
t2
.
id
;
delete
federated
.
t1
.*
,
federated
.
t2
.*
from
federated
.
t1
,
federated
.
t2
where
t1
.
i2
=
t2
.
id
;
select
*
from
federated
.
t1
order
by
i1
;
select
*
from
federated
.
t1
order
by
i1
;
select
*
from
federated
.
t2
order
by
id
;
select
*
from
federated
.
t2
order
by
id
;
drop
table
federated
.
t1
,
federated
.
t2
;
drop
table
federated
.
t1
,
federated
.
t2
;
connection
slave
;
connection
slave
;
drop
table
federated
.
t1
,
federated
.
t2
;
drop
table
federated
.
t1
,
federated
.
t2
;
connection
master
;
# Test multi updates and deletes with keys
# Test multi updates and deletes with keys
connection
slave
;
connection
slave
;
create
table
federated
.
t1
(
i1
int
,
i2
int
,
i3
int
,
primary
key
(
i1
));
create
table
federated
.
t1
(
i1
int
,
i2
int
,
i3
int
,
primary
key
(
i1
));
create
table
federated
.
t2
(
id
int
,
c1
varchar
(
20
),
c2
varchar
(
20
),
primary
key
(
id
));
create
table
federated
.
t2
(
id
int
,
c1
varchar
(
20
),
c2
varchar
(
20
),
primary
key
(
id
));
connection
master
;
connection
master
;
eval
create
table
federated
.
t1
(
i1
int
auto_increment
not
null
,
i2
int
,
i3
int
,
primary
key
(
i1
))
ENGINE
=
FEDERATED
ENGINE
=
FEDERATED
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'
;
--
replace_result
$SLAVE_MYPORT
SLAVE_PORT
eval
create
table
federated
.
t2
(
id
int
auto_increment
not
null
,
c1
varchar
(
20
),
c2
varchar
(
20
),
primary
key
(
id
))
ENGINE
=
FEDERATED
ENGINE
=
FEDERATED
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t2'
;
eval
create
table
federated
.
t1
(
i1
int
auto_increment
not
null
,
i2
int
,
i3
int
,
primary
key
(
i1
))
ENGINE
=
FEDERATED
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'
;
--
replace_result
$SLAVE_MYPORT
SLAVE_PORT
eval
create
table
federated
.
t2
(
id
int
auto_increment
not
null
,
c1
varchar
(
20
),
c2
varchar
(
20
),
primary
key
(
id
))
ENGINE
=
FEDERATED
CONNECTION
=
'mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t2'
;
insert
into
federated
.
t1
values
(
1
,
5
,
10
),(
3
,
7
,
12
),(
4
,
5
,
2
),(
9
,
10
,
15
),(
2
,
2
,
2
);
insert
into
federated
.
t1
values
(
1
,
5
,
10
),(
3
,
7
,
12
),(
4
,
5
,
2
),(
9
,
10
,
15
),(
2
,
2
,
2
);
insert
into
federated
.
t2
values
(
9
,
"abc"
,
"def"
),(
5
,
"opq"
,
"lmn"
),(
2
,
"test t"
,
"t test"
);
insert
into
federated
.
t2
values
(
9
,
"abc"
,
"def"
),(
5
,
"opq"
,
"lmn"
),(
2
,
"test t"
,
"t test"
);
select
*
from
federated
.
t1
order
by
i1
;
select
*
from
federated
.
t1
order
by
i1
;
...
@@ -1354,13 +1359,12 @@ select * from federated.t2 order by id;
...
@@ -1354,13 +1359,12 @@ select * from federated.t2 order by id;
update
federated
.
t1
,
federated
.
t2
set
t1
.
i2
=
15
,
t2
.
c2
=
"ppc"
where
t1
.
i1
=
t2
.
id
;
update
federated
.
t1
,
federated
.
t2
set
t1
.
i2
=
15
,
t2
.
c2
=
"ppc"
where
t1
.
i1
=
t2
.
id
;
select
*
from
federated
.
t1
order
by
i1
;
select
*
from
federated
.
t1
order
by
i1
;
select
*
from
federated
.
t2
order
by
id
;
select
*
from
federated
.
t2
order
by
id
;
delete
t1
.*
,
t2
.*
from
federated
.
t1
,
federated
.
t2
where
t1
.
i2
=
t2
.
id
;
delete
federated
.
t1
.*
,
federated
.
t2
.*
from
federated
.
t1
,
federated
.
t2
where
t1
.
i2
=
t2
.
id
;
select
*
from
federated
.
t1
order
by
i1
;
select
*
from
federated
.
t1
order
by
i1
;
select
*
from
federated
.
t2
order
by
id
;
select
*
from
federated
.
t2
order
by
id
;
drop
table
federated
.
t1
,
federated
.
t2
;
drop
table
federated
.
t1
,
federated
.
t2
;
connection
slave
;
connection
slave
;
drop
table
federated
.
t1
,
federated
.
t2
;
drop
table
federated
.
t1
,
federated
.
t2
;
connection
master
;
--
enable_parsing
--
source
include
/
federated_cleanup
.
inc
source
include
/
federated_cleanup
.
inc
;
sql/ha_federated.cc
View file @
69bf342a
...
@@ -32,13 +32,14 @@
...
@@ -32,13 +32,14 @@
so to read, that data has to be parsed into fields, to write, fields have to
so to read, that data has to be parsed into fields, to write, fields have to
be stored in this format to write to this data file.
be stored in this format to write to this data file.
With MySQL Federated storage engine, there will be no local files for each
With MySQL Federated storage engine, there will be no local files
table's data (such as .MYD). A foreign database will store the data that would
for each table's data (such as .MYD). A foreign database will store
normally be in this file. This will necessitate the use of MySQL client API
the data that would normally be in this file. This will necessitate
to read, delete, update, insert this data. The data will have to be retrieve
the use of MySQL client API to read, delete, update, insert this
via an SQL call "SELECT * FROM users". Then, to read this data, it will have
data. The data will have to be retrieve via an SQL call "SELECT *
to be retrieved via mysql_fetch_row one row at a time, then converted from
FROM users". Then, to read this data, it will have to be retrieved
the column in this select into the format that the handler expects.
via mysql_fetch_row one row at a time, then converted from the
column in this select into the format that the handler expects.
The create table will simply create the .frm file, and within the
The create table will simply create the .frm file, and within the
"CREATE TABLE" SQL, there SHALL be any of the following :
"CREATE TABLE" SQL, there SHALL be any of the following :
...
@@ -385,8 +386,8 @@ static handler *federated_create_handler(TABLE_SHARE *table,
...
@@ -385,8 +386,8 @@ static handler *federated_create_handler(TABLE_SHARE *table,
static
byte
*
federated_get_key
(
FEDERATED_SHARE
*
share
,
uint
*
length
,
static
byte
*
federated_get_key
(
FEDERATED_SHARE
*
share
,
uint
*
length
,
my_bool
not_used
__attribute__
((
unused
)))
my_bool
not_used
__attribute__
((
unused
)))
{
{
*
length
=
share
->
table_name
_length
;
*
length
=
share
->
connect_string
_length
;
return
(
byte
*
)
share
->
table_na
me
;
return
(
byte
*
)
share
->
sche
me
;
}
}
/*
/*
...
@@ -415,7 +416,7 @@ int federated_db_init()
...
@@ -415,7 +416,7 @@ int federated_db_init()
if
(
pthread_mutex_init
(
&
federated_mutex
,
MY_MUTEX_INIT_FAST
))
if
(
pthread_mutex_init
(
&
federated_mutex
,
MY_MUTEX_INIT_FAST
))
goto
error
;
goto
error
;
if
(
!
hash_init
(
&
federated_open_tables
,
system_charset_info
,
32
,
0
,
0
,
if
(
!
hash_init
(
&
federated_open_tables
,
&
my_charset_bin
,
32
,
0
,
0
,
(
hash_get_key
)
federated_get_key
,
0
,
0
))
(
hash_get_key
)
federated_get_key
,
0
,
0
))
{
{
federated_init
=
TRUE
;
federated_init
=
TRUE
;
...
@@ -510,6 +511,7 @@ static int check_foreign_data_source(FEDERATED_SHARE *share,
...
@@ -510,6 +511,7 @@ static int check_foreign_data_source(FEDERATED_SHARE *share,
}
}
else
else
{
{
int
escaped_table_name_length
=
0
;
/*
/*
Since we do not support transactions at this version, we can let the
Since we do not support transactions at this version, we can let the
client API silently reconnect. For future versions, we will need more
client API silently reconnect. For future versions, we will need more
...
@@ -528,17 +530,16 @@ static int check_foreign_data_source(FEDERATED_SHARE *share,
...
@@ -528,17 +530,16 @@ static int check_foreign_data_source(FEDERATED_SHARE *share,
query
.
append
(
FEDERATED_STAR
);
query
.
append
(
FEDERATED_STAR
);
query
.
append
(
FEDERATED_FROM
);
query
.
append
(
FEDERATED_FROM
);
query
.
append
(
FEDERATED_BTICK
);
query
.
append
(
FEDERATED_BTICK
);
escape_string_for_mysql
(
&
my_charset_bin
,
(
char
*
)
escaped_table_name
,
escaped_table_name_length
=
escape_string_for_mysql
(
&
my_charset_bin
,
(
char
*
)
escaped_table_name
,
sizeof
(
escaped_table_name
),
sizeof
(
escaped_table_name
),
share
->
table_name
,
share
->
table_name
,
share
->
table_name_length
);
share
->
table_name_length
);
query
.
append
(
escaped_table_name
);
query
.
append
(
escaped_table_name
,
escaped_table_name_length
);
query
.
append
(
FEDERATED_BTICK
);
query
.
append
(
FEDERATED_BTICK
);
query
.
append
(
FEDERATED_WHERE
);
query
.
append
(
FEDERATED_WHERE
);
query
.
append
(
FEDERATED_FALSE
);
query
.
append
(
FEDERATED_FALSE
);
DBUG_PRINT
(
"info"
,
(
"check_foreign_data_source query %s"
,
query
.
c_ptr_quick
()));
if
(
mysql_real_query
(
mysql
,
query
.
ptr
(),
query
.
length
()))
if
(
mysql_real_query
(
mysql
,
query
.
ptr
(),
query
.
length
()))
{
{
error_code
=
table_create_flag
?
error_code
=
table_create_flag
?
...
@@ -632,8 +633,7 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
...
@@ -632,8 +633,7 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
share
->
scheme
=
my_strndup
(
table
->
s
->
connect_string
.
str
,
share
->
scheme
=
my_strndup
(
table
->
s
->
connect_string
.
str
,
table
->
s
->
connect_string
.
length
,
MYF
(
0
));
table
->
s
->
connect_string
.
length
,
MYF
(
0
));
// Add a null for later termination of table name
share
->
connect_string_length
=
table
->
s
->
connect_string
.
length
;
share
->
scheme
[
table
->
s
->
connect_string
.
length
]
=
0
;
DBUG_PRINT
(
"info"
,(
"parse_url alloced share->scheme %lx"
,
share
->
scheme
));
DBUG_PRINT
(
"info"
,(
"parse_url alloced share->scheme %lx"
,
share
->
scheme
));
/*
/*
...
@@ -735,8 +735,7 @@ error:
...
@@ -735,8 +735,7 @@ error:
ha_federated
::
ha_federated
(
TABLE_SHARE
*
table_arg
)
ha_federated
::
ha_federated
(
TABLE_SHARE
*
table_arg
)
:
handler
(
&
federated_hton
,
table_arg
),
:
handler
(
&
federated_hton
,
table_arg
),
mysql
(
0
),
stored_result
(
0
),
mysql
(
0
),
stored_result
(
0
)
ref_length
(
sizeof
(
MYSQL_ROW_OFFSET
)),
current_position
(
0
)
{
{
trx_next
=
0
;
trx_next
=
0
;
}
}
...
@@ -749,6 +748,7 @@ ha_federated::ha_federated(TABLE_SHARE *table_arg)
...
@@ -749,6 +748,7 @@ ha_federated::ha_federated(TABLE_SHARE *table_arg)
convert_row_to_internal_format()
convert_row_to_internal_format()
record Byte pointer to record
record Byte pointer to record
row MySQL result set row from fetchrow()
row MySQL result set row from fetchrow()
result Result set to use
DESCRIPTION
DESCRIPTION
This method simply iterates through a row returned via fetchrow with
This method simply iterates through a row returned via fetchrow with
...
@@ -761,15 +761,16 @@ ha_federated::ha_federated(TABLE_SHARE *table_arg)
...
@@ -761,15 +761,16 @@ ha_federated::ha_federated(TABLE_SHARE *table_arg)
0 After fields have had field values stored from record
0 After fields have had field values stored from record
*/
*/
uint
ha_federated
::
convert_row_to_internal_format
(
byte
*
record
,
MYSQL_ROW
row
)
uint
ha_federated
::
convert_row_to_internal_format
(
byte
*
record
,
MYSQL_ROW
row
,
MYSQL_RES
*
result
)
{
{
ulong
*
lengths
;
ulong
*
lengths
;
Field
**
field
;
Field
**
field
;
my_bitmap_map
*
old_map
=
dbug_tmp_use_all_columns
(
table
,
table
->
write_set
);
my_bitmap_map
*
old_map
=
dbug_tmp_use_all_columns
(
table
,
table
->
write_set
);
DBUG_ENTER
(
"ha_federated::convert_row_to_internal_format"
);
DBUG_ENTER
(
"ha_federated::convert_row_to_internal_format"
);
lengths
=
mysql_fetch_lengths
(
stored_result
);
lengths
=
mysql_fetch_lengths
(
result
);
memset
(
record
,
0
,
table
->
s
->
null_bytes
);
for
(
field
=
table
->
field
;
*
field
;
field
++
,
row
++
,
lengths
++
)
for
(
field
=
table
->
field
;
*
field
;
field
++
,
row
++
,
lengths
++
)
{
{
...
@@ -1314,12 +1315,11 @@ err:
...
@@ -1314,12 +1315,11 @@ err:
static
FEDERATED_SHARE
*
get_share
(
const
char
*
table_name
,
TABLE
*
table
)
static
FEDERATED_SHARE
*
get_share
(
const
char
*
table_name
,
TABLE
*
table
)
{
{
char
*
select_query
,
*
tmp_table_name
;
char
*
select_query
;
char
query_buffer
[
FEDERATED_QUERY_BUFFER_SIZE
];
char
query_buffer
[
FEDERATED_QUERY_BUFFER_SIZE
];
uint
tmp_table_name_length
;
Field
**
field
;
Field
**
field
;
String
query
(
query_buffer
,
sizeof
(
query_buffer
),
&
my_charset_bin
);
String
query
(
query_buffer
,
sizeof
(
query_buffer
),
&
my_charset_bin
);
FEDERATED_SHARE
*
share
;
FEDERATED_SHARE
*
share
=
NULL
,
tmp_share
;
/*
/*
In order to use this string, we must first zero it's length,
In order to use this string, we must first zero it's length,
or it will contain garbage
or it will contain garbage
...
@@ -1327,12 +1327,15 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
...
@@ -1327,12 +1327,15 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
query
.
length
(
0
);
query
.
length
(
0
);
pthread_mutex_lock
(
&
federated_mutex
);
pthread_mutex_lock
(
&
federated_mutex
);
tmp_table_name
=
table
->
s
->
table_name
.
str
;
tmp_table_name_length
=
table
->
s
->
table_name
.
length
;
if
(
parse_url
(
&
tmp_share
,
table
,
0
))
goto
error
;
/* TODO: change tmp_share.scheme to LEX_STRING object */
if
(
!
(
share
=
(
FEDERATED_SHARE
*
)
hash_search
(
&
federated_open_tables
,
if
(
!
(
share
=
(
FEDERATED_SHARE
*
)
hash_search
(
&
federated_open_tables
,
(
byte
*
)
table_name
,
(
byte
*
)
tmp_share
.
scheme
,
tmp_table_name_length
)))
tmp_share
.
connect_string_length
)))
{
{
query
.
set_charset
(
system_charset_info
);
query
.
set_charset
(
system_charset_info
);
query
.
append
(
FEDERATED_SELECT
);
query
.
append
(
FEDERATED_SELECT
);
...
@@ -1350,18 +1353,15 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
...
@@ -1350,18 +1353,15 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
if
(
!
(
share
=
(
FEDERATED_SHARE
*
)
if
(
!
(
share
=
(
FEDERATED_SHARE
*
)
my_multi_malloc
(
MYF
(
MY_WME
),
my_multi_malloc
(
MYF
(
MY_WME
),
&
share
,
sizeof
(
*
share
),
&
share
,
sizeof
(
*
share
),
&
tmp_table_name
,
tmp_table_name_length
+
1
,
&
select_query
,
&
select_query
,
query
.
length
()
+
table
->
s
->
connect_string
.
length
+
1
,
query
.
length
()
+
table
->
s
->
connect_string
.
length
+
1
,
NullS
)))
NullS
)))
{
pthread_mutex_unlock
(
&
federated_mutex
);
return
NULL
;
}
if
(
parse_url
(
share
,
table
,
0
))
goto
error
;
goto
error
;
memcpy
(
share
,
&
tmp_share
,
sizeof
(
tmp_share
));
share
->
table_name_length
=
strlen
(
share
->
table_name
);
/* TODO: share->table_name to LEX_STRING object */
query
.
append
(
share
->
table_name
,
share
->
table_name_length
);
query
.
append
(
share
->
table_name
,
share
->
table_name_length
);
query
.
append
(
FEDERATED_BTICK
);
query
.
append
(
FEDERATED_BTICK
);
share
->
select_query
=
select_query
;
share
->
select_query
=
select_query
;
...
@@ -1382,11 +1382,8 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
...
@@ -1382,11 +1382,8 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
error:
error:
pthread_mutex_unlock
(
&
federated_mutex
);
pthread_mutex_unlock
(
&
federated_mutex
);
if
(
share
->
scheme
)
my_free
((
gptr
)
tmp_share
.
scheme
,
MYF
(
MY_ALLOW_ZERO_PTR
));
{
my_free
((
gptr
)
share
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
((
gptr
)
share
->
scheme
,
MYF
(
0
));
share
->
scheme
=
0
;
}
return
NULL
;
return
NULL
;
}
}
...
@@ -1406,13 +1403,7 @@ static int free_share(FEDERATED_SHARE *share)
...
@@ -1406,13 +1403,7 @@ static int free_share(FEDERATED_SHARE *share)
{
{
hash_delete
(
&
federated_open_tables
,
(
byte
*
)
share
);
hash_delete
(
&
federated_open_tables
,
(
byte
*
)
share
);
my_free
((
gptr
)
share
->
scheme
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
((
gptr
)
share
->
scheme
,
MYF
(
MY_ALLOW_ZERO_PTR
));
share
->
scheme
=
0
;
if
(
share
->
socket
)
{
my_free
((
gptr
)
share
->
socket
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
((
gptr
)
share
->
socket
,
MYF
(
MY_ALLOW_ZERO_PTR
));
share
->
socket
=
0
;
}
thr_lock_delete
(
&
share
->
lock
);
thr_lock_delete
(
&
share
->
lock
);
VOID
(
pthread_mutex_destroy
(
&
share
->
mutex
));
VOID
(
pthread_mutex_destroy
(
&
share
->
mutex
));
my_free
((
gptr
)
share
,
MYF
(
0
));
my_free
((
gptr
)
share
,
MYF
(
0
));
...
@@ -1474,7 +1465,7 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
...
@@ -1474,7 +1465,7 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
/* Connect to foreign database mysql_real_connect() */
/* Connect to foreign database mysql_real_connect() */
mysql
=
mysql_init
(
0
);
mysql
=
mysql_init
(
0
);
if
(
!
mysql_real_connect
(
mysql
,
if
(
!
mysql
||
!
mysql
_real_connect
(
mysql
,
share
->
hostname
,
share
->
hostname
,
share
->
username
,
share
->
username
,
share
->
password
,
share
->
password
,
...
@@ -1482,6 +1473,7 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
...
@@ -1482,6 +1473,7 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
share
->
port
,
share
->
port
,
share
->
socket
,
0
))
share
->
socket
,
0
))
{
{
free_share
(
share
);
DBUG_RETURN
(
stash_remote_error
());
DBUG_RETURN
(
stash_remote_error
());
}
}
/*
/*
...
@@ -1491,6 +1483,11 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
...
@@ -1491,6 +1483,11 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
*/
*/
mysql
->
reconnect
=
1
;
mysql
->
reconnect
=
1
;
ref_length
=
(
table
->
s
->
primary_key
!=
MAX_KEY
?
table
->
key_info
[
table
->
s
->
primary_key
].
key_length
:
table
->
s
->
reclength
);
DBUG_PRINT
(
"info"
,
(
"ref_length: %u"
,
ref_length
));
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -1514,12 +1511,11 @@ int ha_federated::close(void)
...
@@ -1514,12 +1511,11 @@ int ha_federated::close(void)
/* free the result set */
/* free the result set */
if
(
stored_result
)
if
(
stored_result
)
{
{
DBUG_PRINT
(
"info"
,
(
"mysql_free_result result at address %lx"
,
stored_result
));
mysql_free_result
(
stored_result
);
mysql_free_result
(
stored_result
);
stored_result
=
0
;
stored_result
=
0
;
}
}
/* Disconnect from mysql */
/* Disconnect from mysql */
if
(
mysql
)
// QQ is this really needed
mysql_close
(
mysql
);
mysql_close
(
mysql
);
retval
=
free_share
(
share
);
retval
=
free_share
(
share
);
DBUG_RETURN
(
retval
);
DBUG_RETURN
(
retval
);
...
@@ -1686,8 +1682,6 @@ int ha_federated::write_row(byte *buf)
...
@@ -1686,8 +1682,6 @@ int ha_federated::write_row(byte *buf)
/* add the values */
/* add the values */
insert_string
.
append
(
values_string
);
insert_string
.
append
(
values_string
);
DBUG_PRINT
(
"info"
,
(
"insert query %s"
,
insert_string
.
c_ptr_quick
()));
if
(
mysql_real_query
(
mysql
,
insert_string
.
ptr
(),
insert_string
.
length
()))
if
(
mysql_real_query
(
mysql
,
insert_string
.
ptr
(),
insert_string
.
length
()))
{
{
DBUG_RETURN
(
stash_remote_error
());
DBUG_RETURN
(
stash_remote_error
());
...
@@ -1919,7 +1913,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
...
@@ -1919,7 +1913,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
/*
/*
This will delete a row. 'buf' will contain a copy of the row to be =deleted.
This will delete a row. 'buf' will contain a copy of the row to be =deleted.
The server will call this right after the current row has been called (from
The server will call this right after the current row has been called (from
either a previous rnd_nex
T
() or index call).
either a previous rnd_nex
t
() or index call).
If you keep a pointer to the last row or can access a primary key it will
If you keep a pointer to the last row or can access a primary key it will
make doing the deletion quite a bit easier.
make doing the deletion quite a bit easier.
Keep in mind that the server does no guarentee consecutive deletions.
Keep in mind that the server does no guarentee consecutive deletions.
...
@@ -1985,6 +1979,7 @@ int ha_federated::delete_row(const byte *buf)
...
@@ -1985,6 +1979,7 @@ int ha_federated::delete_row(const byte *buf)
DBUG_RETURN
(
stash_remote_error
());
DBUG_RETURN
(
stash_remote_error
());
}
}
stats
.
deleted
+=
mysql
->
affected_rows
;
stats
.
deleted
+=
mysql
->
affected_rows
;
stats
.
records
-=
mysql
->
affected_rows
;
DBUG_PRINT
(
"info"
,
DBUG_PRINT
(
"info"
,
(
"rows deleted %d rows deleted for all time %d"
,
(
"rows deleted %d rows deleted for all time %d"
,
int
(
mysql
->
affected_rows
),
stats
.
deleted
));
int
(
mysql
->
affected_rows
),
stats
.
deleted
));
...
@@ -2001,12 +1996,15 @@ int ha_federated::delete_row(const byte *buf)
...
@@ -2001,12 +1996,15 @@ int ha_federated::delete_row(const byte *buf)
*/
*/
int
ha_federated
::
index_read
(
byte
*
buf
,
const
byte
*
key
,
int
ha_federated
::
index_read
(
byte
*
buf
,
const
byte
*
key
,
uint
key_len
,
enum
ha_rkey_function
find_flag
)
uint
key_len
,
ha_rkey_function
find_flag
)
{
{
int
retval
;
DBUG_ENTER
(
"ha_federated::index_read"
);
DBUG_ENTER
(
"ha_federated::index_read"
);
retval
=
index_read_idx
(
buf
,
active_index
,
key
,
key_len
,
find_flag
);
DBUG_RETURN
(
retval
);
if
(
stored_result
)
mysql_free_result
(
stored_result
);
DBUG_RETURN
(
index_read_idx_with_result_set
(
buf
,
active_index
,
key
,
key_len
,
find_flag
,
&
stored_result
));
}
}
...
@@ -2015,12 +2013,45 @@ int ha_federated::index_read(byte *buf, const byte *key,
...
@@ -2015,12 +2013,45 @@ int ha_federated::index_read(byte *buf, const byte *key,
row if any. This is only used to read whole keys.
row if any. This is only used to read whole keys.
This method is called via index_read in the case of a WHERE clause using
This method is called via index_read in the case of a WHERE clause using
a
regular non-primary key index,
OR is called DIRECTLY when the WHERE clause
a
primary key index
OR is called DIRECTLY when the WHERE clause
uses a PRIMARY KEY index.
uses a PRIMARY KEY index.
NOTES
This uses an internal result set that is deleted before function
returns. We need to be able to be calable from ha_rnd_pos()
*/
*/
int
ha_federated
::
index_read_idx
(
byte
*
buf
,
uint
index
,
const
byte
*
key
,
int
ha_federated
::
index_read_idx
(
byte
*
buf
,
uint
index
,
const
byte
*
key
,
uint
key_len
,
enum
ha_rkey_function
find_flag
)
uint
key_len
,
enum
ha_rkey_function
find_flag
)
{
int
retval
;
MYSQL_RES
*
mysql_result
;
DBUG_ENTER
(
"ha_federated::index_read_idx"
);
if
((
retval
=
index_read_idx_with_result_set
(
buf
,
index
,
key
,
key_len
,
find_flag
,
&
mysql_result
)))
DBUG_RETURN
(
retval
);
mysql_free_result
(
mysql_result
);
DBUG_RETURN
(
retval
);
}
/*
Create result set for rows matching query and return first row
RESULT
0 ok In this case *result will contain the result set
table->status == 0
# error In this case *result will contain 0
table->status == STATUS_NOT_FOUND
*/
int
ha_federated
::
index_read_idx_with_result_set
(
byte
*
buf
,
uint
index
,
const
byte
*
key
,
uint
key_len
,
ha_rkey_function
find_flag
,
MYSQL_RES
**
result
)
{
{
int
retval
;
int
retval
;
char
error_buffer
[
FEDERATED_QUERY_BUFFER_SIZE
];
char
error_buffer
[
FEDERATED_QUERY_BUFFER_SIZE
];
...
@@ -2033,8 +2064,9 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
...
@@ -2033,8 +2064,9 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
sizeof
(
sql_query_buffer
),
sizeof
(
sql_query_buffer
),
&
my_charset_bin
);
&
my_charset_bin
);
key_range
range
;
key_range
range
;
DBUG_ENTER
(
"ha_federated::index_read_idx"
);
DBUG_ENTER
(
"ha_federated::index_read_idx
_with_result_set
"
);
*
result
=
0
;
// In case of errors
index_string
.
length
(
0
);
index_string
.
length
(
0
);
sql_query
.
length
(
0
);
sql_query
.
length
(
0
);
statistic_increment
(
table
->
in_use
->
status_var
.
ha_read_key_count
,
statistic_increment
(
table
->
in_use
->
status_var
.
ha_read_key_count
,
...
@@ -2051,20 +2083,6 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
...
@@ -2051,20 +2083,6 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
NULL
,
0
,
0
);
NULL
,
0
,
0
);
sql_query
.
append
(
index_string
);
sql_query
.
append
(
index_string
);
DBUG_PRINT
(
"info"
,
(
"current key %d key value %s index_string value %s length %d"
,
index
,
(
char
*
)
key
,
index_string
.
c_ptr_quick
(),
index_string
.
length
()));
DBUG_PRINT
(
"info"
,
(
"current position %d sql_query %s"
,
current_position
,
sql_query
.
c_ptr_quick
()));
if
(
stored_result
)
{
mysql_free_result
(
stored_result
);
stored_result
=
0
;
}
if
(
mysql_real_query
(
mysql
,
sql_query
.
ptr
(),
sql_query
.
length
()))
if
(
mysql_real_query
(
mysql
,
sql_query
.
ptr
(),
sql_query
.
length
()))
{
{
my_sprintf
(
error_buffer
,
(
error_buffer
,
"error: %d '%s'"
,
my_sprintf
(
error_buffer
,
(
error_buffer
,
"error: %d '%s'"
,
...
@@ -2072,45 +2090,41 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
...
@@ -2072,45 +2090,41 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
retval
=
ER_QUERY_ON_FOREIGN_DATA_SOURCE
;
retval
=
ER_QUERY_ON_FOREIGN_DATA_SOURCE
;
goto
error
;
goto
error
;
}
}
stored_result
=
mysql_store_result
(
mysql
);
if
(
!
(
*
result
=
mysql_store_result
(
mysql
)))
if
(
!
stored_result
)
{
{
retval
=
HA_ERR_END_OF_FILE
;
retval
=
HA_ERR_END_OF_FILE
;
goto
error
;
goto
error
;
}
}
/*
if
(
!
(
retval
=
read_next
(
buf
,
*
result
)))
This basically says that the record in table->record[0] is legal,
DBUG_RETURN
(
retval
);
and that it is ok to use this record, for whatever reason, such
as with a join (without it, joins will not work)
*/
table
->
status
=
0
;
retval
=
rnd_next
(
buf
);
mysql_free_result
(
*
result
);
*
result
=
0
;
table
->
status
=
STATUS_NOT_FOUND
;
DBUG_RETURN
(
retval
);
DBUG_RETURN
(
retval
);
error:
error:
if
(
stored_result
)
{
mysql_free_result
(
stored_result
);
stored_result
=
0
;
}
table
->
status
=
STATUS_NOT_FOUND
;
table
->
status
=
STATUS_NOT_FOUND
;
my_error
(
retval
,
MYF
(
0
),
error_buffer
);
my_error
(
retval
,
MYF
(
0
),
error_buffer
);
DBUG_RETURN
(
retval
);
DBUG_RETURN
(
retval
);
}
}
/* Initialized at each key walk (called multiple times unlike rnd_init()) */
/* Initialized at each key walk (called multiple times unlike rnd_init()) */
int
ha_federated
::
index_init
(
uint
keynr
,
bool
sorted
)
int
ha_federated
::
index_init
(
uint
keynr
,
bool
sorted
)
{
{
DBUG_ENTER
(
"ha_federated::index_init"
);
DBUG_ENTER
(
"ha_federated::index_init"
);
DBUG_PRINT
(
"info"
,
DBUG_PRINT
(
"info"
,
(
"table: '%s' key: %u"
,
table
->
s
->
table_name
,
keynr
));
(
"table: '%s' key: %d"
,
table
->
s
->
table_name
.
str
,
keynr
));
active_index
=
keynr
;
active_index
=
keynr
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
/*
Read first range
*/
int
ha_federated
::
read_range_first
(
const
key_range
*
start_key
,
int
ha_federated
::
read_range_first
(
const
key_range
*
start_key
,
const
key_range
*
end_key
,
const
key_range
*
end_key
,
bool
eq_range
,
bool
sorted
)
bool
eq_range
,
bool
sorted
)
...
@@ -2122,8 +2136,7 @@ int ha_federated::read_range_first(const key_range *start_key,
...
@@ -2122,8 +2136,7 @@ int ha_federated::read_range_first(const key_range *start_key,
&
my_charset_bin
);
&
my_charset_bin
);
DBUG_ENTER
(
"ha_federated::read_range_first"
);
DBUG_ENTER
(
"ha_federated::read_range_first"
);
if
(
start_key
==
NULL
&&
end_key
==
NULL
)
DBUG_ASSERT
(
!
(
start_key
==
NULL
&&
end_key
==
NULL
));
DBUG_RETURN
(
0
);
sql_query
.
length
(
0
);
sql_query
.
length
(
0
);
sql_query
.
append
(
share
->
select_query
);
sql_query
.
append
(
share
->
select_query
);
...
@@ -2131,6 +2144,11 @@ int ha_federated::read_range_first(const key_range *start_key,
...
@@ -2131,6 +2144,11 @@ int ha_federated::read_range_first(const key_range *start_key,
&
table
->
key_info
[
active_index
],
&
table
->
key_info
[
active_index
],
start_key
,
end_key
,
0
,
eq_range
);
start_key
,
end_key
,
0
,
eq_range
);
if
(
stored_result
)
{
mysql_free_result
(
stored_result
);
stored_result
=
0
;
}
if
(
mysql_real_query
(
mysql
,
sql_query
.
ptr
(),
sql_query
.
length
()))
if
(
mysql_real_query
(
mysql
,
sql_query
.
ptr
(),
sql_query
.
length
()))
{
{
retval
=
ER_QUERY_ON_FOREIGN_DATA_SOURCE
;
retval
=
ER_QUERY_ON_FOREIGN_DATA_SOURCE
;
...
@@ -2138,38 +2156,21 @@ int ha_federated::read_range_first(const key_range *start_key,
...
@@ -2138,38 +2156,21 @@ int ha_federated::read_range_first(const key_range *start_key,
}
}
sql_query
.
length
(
0
);
sql_query
.
length
(
0
);
if
(
stored_result
)
if
(
!
(
stored_result
=
mysql_store_result
(
mysql
)))
{
DBUG_PRINT
(
"info"
,
(
"mysql_free_result address %lx"
,
stored_result
));
mysql_free_result
(
stored_result
);
stored_result
=
0
;
}
stored_result
=
mysql_store_result
(
mysql
);
if
(
!
stored_result
)
{
{
retval
=
HA_ERR_END_OF_FILE
;
retval
=
HA_ERR_END_OF_FILE
;
goto
error
;
goto
error
;
}
}
/* This was successful, please let it be known! */
retval
=
read_next
(
table
->
record
[
0
],
stored_result
);
table
->
status
=
0
;
retval
=
rnd_next
(
table
->
record
[
0
]);
DBUG_RETURN
(
retval
);
DBUG_RETURN
(
retval
);
error:
error:
table
->
status
=
STATUS_NOT_FOUND
;
table
->
status
=
STATUS_NOT_FOUND
;
if
(
stored_result
)
{
DBUG_PRINT
(
"info"
,
(
"mysql_free_result address %lx"
,
stored_result
));
mysql_free_result
(
stored_result
);
stored_result
=
0
;
}
DBUG_RETURN
(
retval
);
DBUG_RETURN
(
retval
);
}
}
int
ha_federated
::
read_range_next
()
int
ha_federated
::
read_range_next
()
{
{
int
retval
;
int
retval
;
...
@@ -2182,13 +2183,13 @@ int ha_federated::read_range_next()
...
@@ -2182,13 +2183,13 @@ int ha_federated::read_range_next()
/* Used to read forward through the index. */
/* Used to read forward through the index. */
int
ha_federated
::
index_next
(
byte
*
buf
)
int
ha_federated
::
index_next
(
byte
*
buf
)
{
{
int
retval
;
DBUG_ENTER
(
"ha_federated::index_next"
);
DBUG_ENTER
(
"ha_federated::index_next"
);
statistic_increment
(
table
->
in_use
->
status_var
.
ha_read_next_count
,
statistic_increment
(
table
->
in_use
->
status_var
.
ha_read_next_count
,
&
LOCK_status
);
&
LOCK_status
);
retval
=
rnd_next
(
buf
);
DBUG_RETURN
(
read_next
(
buf
,
stored_result
));
DBUG_RETURN
(
retval
);
}
}
/*
/*
rnd_init() is called when the system wants the storage engine to do a table
rnd_init() is called when the system wants the storage engine to do a table
scan.
scan.
...
@@ -2242,11 +2243,8 @@ int ha_federated::rnd_init(bool scan)
...
@@ -2242,11 +2243,8 @@ int ha_federated::rnd_init(bool scan)
if
(
scan
)
if
(
scan
)
{
{
DBUG_PRINT
(
"info"
,
(
"share->select_query %s"
,
share
->
select_query
));
if
(
stored_result
)
if
(
stored_result
)
{
{
DBUG_PRINT
(
"info"
,
(
"mysql_free_result address %lx"
,
stored_result
));
mysql_free_result
(
stored_result
);
mysql_free_result
(
stored_result
);
stored_result
=
0
;
stored_result
=
0
;
}
}
...
@@ -2266,25 +2264,22 @@ error:
...
@@ -2266,25 +2264,22 @@ error:
DBUG_RETURN
(
stash_remote_error
());
DBUG_RETURN
(
stash_remote_error
());
}
}
int
ha_federated
::
rnd_end
()
int
ha_federated
::
rnd_end
()
{
{
int
retval
;
DBUG_ENTER
(
"ha_federated::rnd_end"
);
DBUG_ENTER
(
"ha_federated::rnd_end"
);
DBUG_RETURN
(
index_end
());
if
(
stored_result
)
{
DBUG_PRINT
(
"info"
,
(
"mysql_free_result address %lx"
,
stored_result
));
mysql_free_result
(
stored_result
);
stored_result
=
0
;
}
retval
=
index_end
();
DBUG_RETURN
(
retval
);
}
}
int
ha_federated
::
index_end
(
void
)
int
ha_federated
::
index_end
(
void
)
{
{
DBUG_ENTER
(
"ha_federated::index_end"
);
DBUG_ENTER
(
"ha_federated::index_end"
);
if
(
stored_result
)
{
mysql_free_result
(
stored_result
);
stored_result
=
0
;
}
active_index
=
MAX_KEY
;
active_index
=
MAX_KEY
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -2302,8 +2297,6 @@ int ha_federated::index_end(void)
...
@@ -2302,8 +2297,6 @@ int ha_federated::index_end(void)
int
ha_federated
::
rnd_next
(
byte
*
buf
)
int
ha_federated
::
rnd_next
(
byte
*
buf
)
{
{
int
retval
;
MYSQL_ROW
row
;
DBUG_ENTER
(
"ha_federated::rnd_next"
);
DBUG_ENTER
(
"ha_federated::rnd_next"
);
if
(
stored_result
==
0
)
if
(
stored_result
==
0
)
...
@@ -2311,32 +2304,60 @@ int ha_federated::rnd_next(byte *buf)
...
@@ -2311,32 +2304,60 @@ int ha_federated::rnd_next(byte *buf)
/*
/*
Return value of rnd_init is not always checked (see records.cc),
Return value of rnd_init is not always checked (see records.cc),
so we can get here _even_ if there is _no_ pre-fetched result-set!
so we can get here _even_ if there is _no_ pre-fetched result-set!
TODO: fix it.
TODO: fix it.
We can delete this in 5.1 when rnd_init() is checked.
*/
*/
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
}
DBUG_RETURN
(
read_next
(
buf
,
stored_result
));
}
/*
ha_federated::read_next
reads from a result set and converts to mysql internal
format
SYNOPSIS
field_in_record_is_null()
buf byte pointer to record
result mysql result set
DESCRIPTION
This method is a wrapper method that reads one record from a result
set and converts it to the internal table format
RETURN VALUE
1 error
0 no error
*/
int
ha_federated
::
read_next
(
byte
*
buf
,
MYSQL_RES
*
result
)
{
int
retval
;
my_ulonglong
num_rows
;
MYSQL_ROW
row
;
DBUG_ENTER
(
"ha_federated::read_next"
);
table
->
status
=
STATUS_NOT_FOUND
;
// For easier return
/* Fetch a row, insert it back in a row format. */
/* Fetch a row, insert it back in a row format. */
current_position
=
stored_result
->
data_cursor
;
if
(
!
(
row
=
mysql_fetch_row
(
result
)))
DBUG_PRINT
(
"info"
,
(
"current position %d"
,
current_position
));
if
(
!
(
row
=
mysql_fetch_row
(
stored_result
)))
DBUG_RETURN
(
HA_ERR_END_OF_FILE
);
DBUG_RETURN
(
HA_ERR_END_OF_FILE
);
retval
=
convert_row_to_internal_format
(
buf
,
row
);
if
(
!
(
retval
=
convert_row_to_internal_format
(
buf
,
row
,
result
)))
table
->
status
=
0
;
DBUG_RETURN
(
retval
);
DBUG_RETURN
(
retval
);
}
}
/*
/*
'position()' is called after each call to rnd_next() if the data needs to be
store reference to current row so that we can later find it for
ordered. You can do something like the following to store the position:
a re-read, update or delete.
my_store_ptr(ref, ref_length, current_position);
The server uses ref to store data. ref_length in the above case is the size
In case of federated, a reference is either a primary key or
needed to store current_position. ref is just a byte array that the server
the whole record.
will maintain. If you are using offsets to mark rows, then current_position
should be the offset. If it is a primary key like in BDB, then it needs to
be a primary key.
Called from filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc.
Called from filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc.
*/
*/
...
@@ -2344,32 +2365,44 @@ int ha_federated::rnd_next(byte *buf)
...
@@ -2344,32 +2365,44 @@ int ha_federated::rnd_next(byte *buf)
void
ha_federated
::
position
(
const
byte
*
record
)
void
ha_federated
::
position
(
const
byte
*
record
)
{
{
DBUG_ENTER
(
"ha_federated::position"
);
DBUG_ENTER
(
"ha_federated::position"
);
/* my_store_ptr Add seek storage */
if
(
table
->
s
->
primary_key
!=
MAX_KEY
)
*
(
MYSQL_ROW_OFFSET
*
)
ref
=
current_position
;
// ref is always aligned
key_copy
(
ref
,
(
byte
*
)
record
,
table
->
key_info
+
table
->
s
->
primary_key
,
ref_length
);
else
memcpy
(
ref
,
record
,
ref_length
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
/*
/*
This is like rnd_next, but you are given a position to use to determine the
This is like rnd_next, but you are given a position to use to determine the
row. The position will be of the type that you stored in ref. You can use
row. The position will be of the type that you stored in ref.
ha_get_ptr(pos,ref_length) to retrieve whatever key or position you saved
when position() was called.
This method is required for an ORDER BY
.
This method is required for an ORDER BY
Called from filesort.cc records.cc sql_insert.cc sql_select.cc sql_update.cc.
Called from filesort.cc records.cc sql_insert.cc sql_select.cc sql_update.cc.
*/
*/
int
ha_federated
::
rnd_pos
(
byte
*
buf
,
byte
*
pos
)
int
ha_federated
::
rnd_pos
(
byte
*
buf
,
byte
*
pos
)
{
{
int
result
;
DBUG_ENTER
(
"ha_federated::rnd_pos"
);
DBUG_ENTER
(
"ha_federated::rnd_pos"
);
statistic_increment
(
table
->
in_use
->
status_var
.
ha_read_rnd_count
,
statistic_increment
(
table
->
in_use
->
status_var
.
ha_read_rnd_count
,
&
LOCK_status
);
&
LOCK_status
);
memcpy_fixed
(
&
current_position
,
pos
,
sizeof
(
MYSQL_ROW_OFFSET
));
if
(
table
->
s
->
primary_key
!=
MAX_KEY
)
stored_result
->
current_row
=
0
;
{
stored_result
->
data_cursor
=
current_position
;
/* We have a primary key, so use index_read_idx to find row */
DBUG_RETURN
(
rnd_next
(
buf
));
result
=
index_read_idx
(
buf
,
table
->
s
->
primary_key
,
pos
,
ref_length
,
HA_READ_KEY_EXACT
);
}
else
{
/* otherwise, get the old record ref as obtained in ::position */
memcpy
(
buf
,
pos
,
ref_length
);
result
=
0
;
}
table
->
status
=
result
?
STATUS_NOT_FOUND
:
0
;
DBUG_RETURN
(
result
);
}
}
...
@@ -2477,8 +2510,10 @@ void ha_federated::info(uint flag)
...
@@ -2477,8 +2510,10 @@ void ha_federated::info(uint flag)
stats
.
records
=
(
ha_rows
)
my_strtoll10
(
row
[
4
],
(
char
**
)
0
,
stats
.
records
=
(
ha_rows
)
my_strtoll10
(
row
[
4
],
(
char
**
)
0
,
&
error
);
&
error
);
if
(
row
[
5
]
!=
NULL
)
if
(
row
[
5
]
!=
NULL
)
stats
.
mean_rec_length
=
(
ha_rows
)
my_strtoll10
(
row
[
5
],
(
char
**
)
0
,
stats
.
mean_rec_length
=
(
ha_rows
)
my_strtoll10
(
row
[
5
],
(
char
**
)
0
,
&
error
);
&
error
);
stats
.
data_file_length
=
stats
.
records
*
stats
.
mean_rec_length
;
if
(
row
[
12
]
!=
NULL
)
if
(
row
[
12
]
!=
NULL
)
stats
.
update_time
=
(
ha_rows
)
my_strtoll10
(
row
[
12
],
(
char
**
)
0
,
stats
.
update_time
=
(
ha_rows
)
my_strtoll10
(
row
[
12
],
(
char
**
)
0
,
&
error
);
&
error
);
...
@@ -2486,8 +2521,13 @@ void ha_federated::info(uint flag)
...
@@ -2486,8 +2521,13 @@ void ha_federated::info(uint flag)
stats
.
check_time
=
(
ha_rows
)
my_strtoll10
(
row
[
13
],
(
char
**
)
0
,
stats
.
check_time
=
(
ha_rows
)
my_strtoll10
(
row
[
13
],
(
char
**
)
0
,
&
error
);
&
error
);
}
}
/*
size of IO operations (This is based on a good guess, no high science
involved)
*/
if
(
flag
&
HA_STATUS_CONST
)
if
(
flag
&
HA_STATUS_CONST
)
stats
.
block_size
=
4096
;
stats
.
block_size
=
4096
;
}
}
if
(
result
)
if
(
result
)
...
@@ -2498,6 +2538,7 @@ void ha_federated::info(uint flag)
...
@@ -2498,6 +2538,7 @@ void ha_federated::info(uint flag)
error:
error:
if
(
result
)
if
(
result
)
mysql_free_result
(
result
);
mysql_free_result
(
result
);
my_sprintf
(
error_buffer
,
(
error_buffer
,
": %d : %s"
,
my_sprintf
(
error_buffer
,
(
error_buffer
,
": %d : %s"
,
mysql_errno
(
mysql
),
mysql_error
(
mysql
)));
mysql_errno
(
mysql
),
mysql_error
(
mysql
)));
my_error
(
error_code
,
MYF
(
0
),
error_buffer
);
my_error
(
error_code
,
MYF
(
0
),
error_buffer
);
...
@@ -2578,6 +2619,7 @@ THR_LOCK_DATA **ha_federated::store_lock(THD *thd,
...
@@ -2578,6 +2619,7 @@ THR_LOCK_DATA **ha_federated::store_lock(THD *thd,
THR_LOCK_DATA
**
to
,
THR_LOCK_DATA
**
to
,
enum
thr_lock_type
lock_type
)
enum
thr_lock_type
lock_type
)
{
{
DBUG_ENTER
(
"ha_federated::store_lock"
);
if
(
lock_type
!=
TL_IGNORE
&&
lock
.
type
==
TL_UNLOCK
)
if
(
lock_type
!=
TL_IGNORE
&&
lock
.
type
==
TL_UNLOCK
)
{
{
/*
/*
...
@@ -2607,7 +2649,7 @@ THR_LOCK_DATA **ha_federated::store_lock(THD *thd,
...
@@ -2607,7 +2649,7 @@ THR_LOCK_DATA **ha_federated::store_lock(THD *thd,
*
to
++=
&
lock
;
*
to
++=
&
lock
;
return
to
;
DBUG_RETURN
(
to
)
;
}
}
/*
/*
...
...
sql/ha_federated.h
View file @
69bf342a
...
@@ -130,6 +130,7 @@ typedef struct st_federated_share {
...
@@ -130,6 +130,7 @@ typedef struct st_federated_share {
remote host info, parse_url supplies
remote host info, parse_url supplies
*/
*/
char
*
scheme
;
char
*
scheme
;
char
*
connect_string
;
char
*
hostname
;
char
*
hostname
;
char
*
username
;
char
*
username
;
char
*
password
;
char
*
password
;
...
@@ -139,7 +140,7 @@ typedef struct st_federated_share {
...
@@ -139,7 +140,7 @@ typedef struct st_federated_share {
char
*
socket
;
char
*
socket
;
char
*
sport
;
char
*
sport
;
ushort
port
;
ushort
port
;
uint
table_name_length
,
use_count
;
uint
table_name_length
,
connect_string_length
,
use_count
;
pthread_mutex_t
mutex
;
pthread_mutex_t
mutex
;
THR_LOCK
lock
;
THR_LOCK
lock
;
}
FEDERATED_SHARE
;
}
FEDERATED_SHARE
;
...
@@ -153,7 +154,6 @@ class ha_federated: public handler
...
@@ -153,7 +154,6 @@ class ha_federated: public handler
FEDERATED_SHARE
*
share
;
/* Shared lock info */
FEDERATED_SHARE
*
share
;
/* Shared lock info */
MYSQL
*
mysql
;
/* MySQL connection */
MYSQL
*
mysql
;
/* MySQL connection */
MYSQL_RES
*
stored_result
;
MYSQL_RES
*
stored_result
;
uint
ref_length
;
uint
fetch_num
;
// stores the fetch num
uint
fetch_num
;
// stores the fetch num
MYSQL_ROW_OFFSET
current_position
;
// Current position used by ::position()
MYSQL_ROW_OFFSET
current_position
;
// Current position used by ::position()
int
remote_error_number
;
int
remote_error_number
;
...
@@ -164,7 +164,8 @@ private:
...
@@ -164,7 +164,8 @@ private:
return 0 on success
return 0 on success
return errorcode otherwise
return errorcode otherwise
*/
*/
uint
convert_row_to_internal_format
(
byte
*
buf
,
MYSQL_ROW
row
);
uint
convert_row_to_internal_format
(
byte
*
buf
,
MYSQL_ROW
row
,
MYSQL_RES
*
row
);
bool
create_where_from_key
(
String
*
to
,
KEY
*
key_info
,
bool
create_where_from_key
(
String
*
to
,
KEY
*
key_info
,
const
key_range
*
start_key
,
const
key_range
*
start_key
,
const
key_range
*
end_key
,
const
key_range
*
end_key
,
...
@@ -304,6 +305,13 @@ public:
...
@@ -304,6 +305,13 @@ public:
int
connection_rollback
();
int
connection_rollback
();
int
connection_autocommit
(
bool
state
);
int
connection_autocommit
(
bool
state
);
int
execute_simple_query
(
const
char
*
query
,
int
len
);
int
execute_simple_query
(
const
char
*
query
,
int
len
);
int
read_next
(
byte
*
buf
,
MYSQL_RES
*
result
);
int
index_read_idx_with_result_set
(
byte
*
buf
,
uint
index
,
const
byte
*
key
,
uint
key_len
,
ha_rkey_function
find_flag
,
MYSQL_RES
**
result
);
};
};
int
federated_db_init
(
void
);
int
federated_db_init
(
void
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment