Commit 2ee3ef2e authored by unknown's avatar unknown

BUG #19773

  
Final-review fixes per Monty, pre-push. OK'd for 
push. Please see each file's comments.



mysql-test/r/federated.result:
  BUG #19773
      
  Results for multi-table deletes, updates
mysql-test/t/federated.test:
  BUG #19773
      
  Test multi table update and delete. Added drop table to end of previous test.
sql/ha_federated.cc:
  BUG #19773 
      
  Post-review changes, per Monty. 3rd patch, OK'd for push.
  - Added index_read_idx_with_result_set, which uses the result set passed to it
  - Hash by entire connection scheme
  - Protected store_result result set for table scan by adding a method result set
    to index_read_idx and index_read which is passed to index_read_with_result, which
    in turn iterates over the single record via read_next.
    This is a change from having two result sets in the first two patches. 
    This keeps the code clean and avoids the need for yet another result set.
  - Rewrote ::position and ::rnd_pos to store position - if primary key use 
    primary key, if not, use record buffer.
  - Rewrote get_share to store hash with connect string vs. table name
  - delete_row added subtration of "records" by affected->rows
  - Added read_next to handle what rnd_next used to do (converting raw record
     to query and vice versa)
  - Removed many DBUG_PRINT lines
  - Removed memset initialisation since subsequent loop accomplishes
  - Removed un-necessary mysql_free_result lines
sql/ha_federated.h:
   BUG #19773
      
      Fixed "SET " to " SET " to make sure built statements are built with 
      "UPDATE `t1` SET .." instead of "UPDATE `t1`SET"
parent edcba744
...@@ -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,6 +1603,92 @@ fld_cid fld_name fld_parentid fld_delt ...@@ -1601,6 +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;
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:9308/federated/t1';
create table federated.t2 (id int, c1 varchar(20), c2 varchar(20)) ENGINE=FEDERATED CONNECTION='mysql://root@127.0.0.1:9308/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:9308/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:9308/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;
......
...@@ -1254,6 +1254,10 @@ SELECT LAST_INSERT_ID(); ...@@ -1254,6 +1254,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
...@@ -1309,5 +1313,52 @@ DROP TABLE federated.t1; ...@@ -1309,5 +1313,52 @@ DROP TABLE federated.t1;
connection slave; connection slave;
DROP TABLE federated.bug_17377_table; DROP TABLE federated.bug_17377_table;
#
# BUG 19773 Crash when using multi-table updates, deletes
# with federated tables
#
connection slave;
create table federated.t1 (i1 int, i2 int, i3 int);
create table federated.t2 (id int, c1 varchar(20), c2 varchar(20));
connection master;
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.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.t2 values (9,"abc","def"),(5,"opq","lmn"),(2,"test t","t test");
select * from federated.t1 order by i1;
select * from federated.t2;
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.t2 order by 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.t2 order by id;
drop table federated.t1, federated.t2;
connection slave;
drop table federated.t1, federated.t2;
# Test multi updates and deletes with keys
connection slave;
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));
connection master;
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';
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.t2 values (9,"abc","def"),(5,"opq","lmn"),(2,"test t","t test");
select * from federated.t1 order by i1;
select * from federated.t2 order by 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.t2 order by 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.t2 order by id;
drop table federated.t1, federated.t2;
connection slave;
drop table federated.t1, federated.t2;
source include/federated_cleanup.inc; source include/federated_cleanup.inc;
This diff is collapsed.
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
#define FEDERATED_VALUES_LEN sizeof(FEDERATED_VALUES) #define FEDERATED_VALUES_LEN sizeof(FEDERATED_VALUES)
#define FEDERATED_UPDATE "UPDATE " #define FEDERATED_UPDATE "UPDATE "
#define FEDERATED_UPDATE_LEN sizeof(FEDERATED_UPDATE) #define FEDERATED_UPDATE_LEN sizeof(FEDERATED_UPDATE)
#define FEDERATED_SET "SET " #define FEDERATED_SET " SET "
#define FEDERATED_SET_LEN sizeof(FEDERATED_SET) #define FEDERATED_SET_LEN sizeof(FEDERATED_SET)
#define FEDERATED_AND " AND " #define FEDERATED_AND " AND "
#define FEDERATED_AND_LEN sizeof(FEDERATED_AND) #define FEDERATED_AND_LEN sizeof(FEDERATED_AND)
...@@ -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,
...@@ -298,6 +299,13 @@ public: ...@@ -298,6 +299,13 @@ public:
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); //required enum thr_lock_type lock_type); //required
virtual bool get_error_message(int error, String *buf); virtual bool get_error_message(int error, String *buf);
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);
}; };
bool federated_db_init(void); bool federated_db_init(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment