diff options
-rw-r--r-- | mysql-test/suite/federated/federatedx_create_handlers.result | 22 | ||||
-rw-r--r-- | mysql-test/suite/federated/federatedx_create_handlers.test | 21 | ||||
-rw-r--r-- | sql/select_handler.cc | 25 | ||||
-rw-r--r-- | storage/federatedx/federatedx_pushdown.cc | 13 |
4 files changed, 57 insertions, 24 deletions
diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result index 473972c2cd4..65a9d52803f 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.result +++ b/mysql-test/suite/federated/federatedx_create_handlers.result @@ -299,7 +299,27 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 7 1 PRIMARY <derived2> ref key0 key0 18 federated.t3.name 2 2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL -DROP TABLE federated.t1, federated.t2, federated.t3; +# +# MDEV-21887: federatedx crashes on SELECT ... INTO query in select_handler code +# +CREATE TABLE federated.t4 ( +id int(20) NOT NULL, +name varchar(16) NOT NULL default '' +) engine=myisam; +insert into federated.t4 select * from federated.t1; +select * from federated.t4; +id name +1 zzz +3 xxx +4 xxx +5 yyy +7 yyy +select name into @var from federated.t1 where id=3 limit 1 ; +select @var; +@var +xxx +select name into outfile 'tmp.txt' from federated.t1; +DROP TABLE federated.t1, federated.t2, federated.t3, federated.t4; connection slave; DROP TABLE federated.t1, federated.t2; connection default; diff --git a/mysql-test/suite/federated/federatedx_create_handlers.test b/mysql-test/suite/federated/federatedx_create_handlers.test index 373b2aaaa33..42a03e60d67 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.test +++ b/mysql-test/suite/federated/federatedx_create_handlers.test @@ -147,8 +147,27 @@ FROM federated.t3, SELECT * FROM federated.t1 WHERE id >= 5) t WHERE federated.t3.name=t.name; +--echo # +--echo # MDEV-21887: federatedx crashes on SELECT ... INTO query in select_handler code +--echo # -DROP TABLE federated.t1, federated.t2, federated.t3; +CREATE TABLE federated.t4 ( + id int(20) NOT NULL, + name varchar(16) NOT NULL default '' +) engine=myisam; +insert into federated.t4 select * from federated.t1; + +--sorted_result +select * from federated.t4; + +select name into @var from federated.t1 where id=3 limit 1 ; +select @var; +select name into outfile 'tmp.txt' from federated.t1; + +let $path=`select concat(@@datadir, 'test/tmp.txt')`; +remove_file $path; + +DROP TABLE federated.t1, federated.t2, federated.t3, federated.t4; connection slave; DROP TABLE federated.t1, federated.t2; diff --git a/sql/select_handler.cc b/sql/select_handler.cc index b364cb12341..495b6d957b1 100644 --- a/sql/select_handler.cc +++ b/sql/select_handler.cc @@ -77,18 +77,17 @@ bool Pushdown_select::init() bool Pushdown_select::send_result_set_metadata() { - THD *thd= handler->thd; - Protocol *protocol= thd->protocol; DBUG_ENTER("Pushdown_select::send_result_set_metadata"); #ifdef WITH_WSREP + THD *thd= handler->thd; if (WSREP(thd) && thd->wsrep_retry_query) { WSREP_DEBUG("skipping select metadata"); DBUG_RETURN(false); } #endif /* WITH_WSREP */ - if (protocol->send_result_set_metadata(&result_columns, + if (select->join->result->send_result_set_metadata(result_columns, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) DBUG_RETURN(true); @@ -100,23 +99,13 @@ bool Pushdown_select::send_result_set_metadata() bool Pushdown_select::send_data() { THD *thd= handler->thd; - Protocol *protocol= thd->protocol; DBUG_ENTER("Pushdown_select::send_data"); if (thd->killed == ABORT_QUERY) DBUG_RETURN(false); - protocol->prepare_for_resend(); - if (protocol->send_result_set_row(&result_columns)) - { - protocol->remove_last_row(); + if (select->join->result->send_data(result_columns)) DBUG_RETURN(true); - } - - thd->inc_sent_row_count(1); - - if (thd->vio_ok()) - DBUG_RETURN(protocol->write()); DBUG_RETURN(false); } @@ -124,16 +113,10 @@ bool Pushdown_select::send_data() bool Pushdown_select::send_eof() { - THD *thd= handler->thd; DBUG_ENTER("Pushdown_select::send_eof"); - /* - Don't send EOF if we're in error condition (which implies we've already - sent or are sending an error) - */ - if (thd->is_error()) + if (select->join->result->send_eof()) DBUG_RETURN(true); - ::my_eof(thd); DBUG_RETURN(false); } diff --git a/storage/federatedx/federatedx_pushdown.cc b/storage/federatedx/federatedx_pushdown.cc index 2bcee943308..15b0b0d3d4e 100644 --- a/storage/federatedx/federatedx_pushdown.cc +++ b/storage/federatedx/federatedx_pushdown.cc @@ -182,6 +182,16 @@ create_federatedx_select_handler(THD* thd, SELECT_LEX *sel) return 0; } + /* + Currently, ha_federatedx_select_handler::init_scan just takes the + thd->query and sends it to the backend. + This obviously won't work if the SELECT uses an "INTO @var" or + "INTO OUTFILE". It is also unlikely to work if the select has some + other kind of side effect. + */ + if (sel->uncacheable & UNCACHEABLE_SIDEEFFECT) + return NULL; + handler= new ha_federatedx_select_handler(thd, sel); return handler; @@ -286,8 +296,9 @@ int ha_federatedx_select_handler::end_scan() DBUG_RETURN(0); } -void ha_federatedx_select_handler::print_error(int, unsigned long) +void ha_federatedx_select_handler::print_error(int error, myf error_flag) { + select_handler::print_error(error, error_flag); } |