[Commits] 23e8c2f: MDEV-17631 select_handler for a full query pushdown
revision-id: 23e8c2f07473bb1bc7d5430e59f60729b9d92e56 (mariadb-10.3.6-132-g23e8c2f) parent(s): a30776dd98d8e7b44e8b3e2bc07c23c0beed2434 author: Igor Babaev committer: Igor Babaev timestamp: 2019-01-27 23:44:27 -0800 message: MDEV-17631 select_handler for a full query pushdown MDEV-17096 Pushdown of simple derived tables to storage engines Fixed leakage problems of the implementation of the interfaces for FEDERATEDX. --- .../federated/federatedx_create_handlers.result | 110 +++++++++++++++++++++ .../federated/federatedx_create_handlers.test | 50 +++++++++- sql/derived_handler.cc | 12 +++ sql/derived_handler.h | 6 +- sql/select_handler.cc | 13 +++ sql/select_handler.h | 10 +- sql/sql_explain.cc | 12 ++- sql/sql_explain.h | 1 + sql/sql_lex.cc | 5 +- sql/sql_select.cc | 27 +++-- sql/sql_select.h | 9 +- storage/federatedx/ha_federatedx.cc | 58 ++++++----- storage/federatedx/ha_federatedx.h | 5 +- 13 files changed, 265 insertions(+), 53 deletions(-) diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result index d32853e..fdad44c 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.result +++ b/mysql-test/suite/federated/federatedx_create_handlers.result @@ -15,6 +15,9 @@ name varchar(16) NOT NULL default '' DEFAULT CHARSET=latin1; INSERT INTO federated.t1 VALUES (3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy'); +DROP TABLE IF EXISTS federated.t2; +Warnings: +Note 1051 Unknown table 'federated.t2' CREATE TABLE federated.t2 ( name varchar(16) NOT NULL default '' ) @@ -31,6 +34,9 @@ name varchar(16) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +DROP TABLE IF EXISTS federated.t2; +Warnings: +Note 1051 Unknown table 'federated.t2' CREATE TABLE federated.t2 ( name varchar(16) NOT NULL default '' ) @@ -80,6 +86,110 @@ WHERE id IN (SELECT count(*) FROM federated.t2 GROUP BY name); id name 3 xxx 1 zzz +EXPLAIN +SELECT id FROM federated.t1 WHERE id < 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL +EXPLAIN EXTENDED +SELECT id FROM federated.t1 WHERE id < 5; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 select `federated`.`t1`.`id` AS `id` from `federated`.`t1` where `federated`.`t1`.`id` < 5 +EXPLAIN FORMAT=JSON +SELECT id FROM federated.t1 WHERE id < 5; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "message": "Pushed select" + } + } +} +ANALYZE +SELECT id FROM federated.t1 WHERE id < 5; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL +ANALYZE FORMAT=JSON +SELECT id FROM federated.t1 WHERE id < 5; +ANALYZE +{ + "query_block": { + "select_id": 1, + "table": { + "message": "Pushed select" + } + } +} +CREATE TABLE federated.t3 ( +name varchar(16) NOT NULL default '' +) +DEFAULT CHARSET=latin1; +INSERT INTO federated.t3 VALUES +('yyy'), ('www'), ('yyy'), ('xxx'), ('www'), ('yyy'), ('www'); +SELECT * +FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t +WHERE federated.t3.name=t.name; +name id name +yyy 5 yyy +yyy 7 yyy +yyy 5 yyy +yyy 7 yyy +xxx 4 xxx +yyy 5 yyy +yyy 7 yyy +EXPLAIN +SELECT * +FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t +WHERE federated.t3.name=t.name; +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 +EXPLAIN FORMAT=JSON +SELECT * +FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t +WHERE federated.t3.name=t.name; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t3", + "access_type": "ALL", + "rows": 7, + "filtered": 100 + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "18", + "used_key_parts": ["name"], + "ref": ["federated.t3.name"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "table": { + "message": "Pushed derived" + } + } + } + } + } +} +ANALYZE +SELECT * +FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t +WHERE federated.t3.name=t.name; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 7 7.00 100.00 100.00 +1 PRIMARY <derived2> ref key0 key0 18 federated.t3.name 2 0.00 100.00 100.00 +2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL DROP TABLE federated.t1, federated.t2; connection slave; DROP TABLE federated.t1, federated.t2; diff --git a/mysql-test/suite/federated/federatedx_create_handlers.test b/mysql-test/suite/federated/federatedx_create_handlers.test index 92a6f3c..0e586da 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.test +++ b/mysql-test/suite/federated/federatedx_create_handlers.test @@ -2,6 +2,7 @@ --source include/federated.inc connection slave; + DROP TABLE IF EXISTS federated.t1; CREATE TABLE federated.t1 ( @@ -13,6 +14,8 @@ DEFAULT CHARSET=latin1; INSERT INTO federated.t1 VALUES (3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy'); +DROP TABLE IF EXISTS federated.t2; + CREATE TABLE federated.t2 ( name varchar(16) NOT NULL default '' ) @@ -23,6 +26,7 @@ INSERT INTO federated.t2 VALUES connection master; + DROP TABLE IF EXISTS federated.t1; --replace_result $SLAVE_MYPORT SLAVE_PORT @@ -34,6 +38,8 @@ CREATE TABLE federated.t1 ( ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; +DROP TABLE IF EXISTS federated.t2; + --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE federated.t2 ( @@ -56,8 +62,50 @@ SELECT * FROM federated.t1 LEFT JOIN federated.t2 WHERE federated.t1.id > 1; SELECT * FROM federated.t1 - WHERE id IN (SELECT count(*) FROM federated.t2 GROUP BY name); + WHERE id IN (SELECT count(*) FROM federated.t2 GROUP BY name); + +EXPLAIN +SELECT id FROM federated.t1 WHERE id < 5; +EXPLAIN EXTENDED +SELECT id FROM federated.t1 WHERE id < 5; + +EXPLAIN FORMAT=JSON +SELECT id FROM federated.t1 WHERE id < 5; + +ANALYZE +SELECT id FROM federated.t1 WHERE id < 5; + +ANALYZE FORMAT=JSON +SELECT id FROM federated.t1 WHERE id < 5; + +CREATE TABLE federated.t3 ( + name varchar(16) NOT NULL default '' +) +DEFAULT CHARSET=latin1; + +INSERT INTO federated.t3 VALUES + ('yyy'), ('www'), ('yyy'), ('xxx'), ('www'), ('yyy'), ('www'); + +SELECT * +FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t +WHERE federated.t3.name=t.name; + +EXPLAIN +SELECT * +FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t +WHERE federated.t3.name=t.name; + +EXPLAIN FORMAT=JSON +SELECT * +FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t +WHERE federated.t3.name=t.name; + +ANALYZE +SELECT * +FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t +WHERE federated.t3.name=t.name; + DROP TABLE federated.t1, federated.t2; connection slave; diff --git a/sql/derived_handler.cc b/sql/derived_handler.cc index dd017fd..561c18a 100644 --- a/sql/derived_handler.cc +++ b/sql/derived_handler.cc @@ -14,6 +14,12 @@ void derived_handler::set_derived(TABLE_LIST *tbl) &select->join->tmp_table_param; } +Pushdown_derived::Pushdown_derived(TABLE_LIST *tbl, derived_handler *h) + : derived(tbl), handler(h) +{ + is_analyze= handler->thd->lex->analyze_stmt; +} + Pushdown_derived::~Pushdown_derived() { delete handler; @@ -31,6 +37,12 @@ int Pushdown_derived::execute() if ((err= handler->init_scan())) goto error; + if (is_analyze) + { + handler->end_scan(); + DBUG_RETURN(0); + } + while (!(err= handler->next_row())) { if (unlikely(thd->check_killed())) diff --git a/sql/derived_handler.h b/sql/derived_handler.h index a7b1294..c312a93 100644 --- a/sql/derived_handler.h +++ b/sql/derived_handler.h @@ -6,6 +6,8 @@ class TMP_TABLE_PARAM; +typedef class st_select_lex_unit SELECT_LEX_UNIT; + class derived_handler { public: @@ -23,9 +25,9 @@ class derived_handler TMP_TABLE_PARAM *tmp_table_param; - struct st_select_lex_unit *unit; + SELECT_LEX_UNIT *unit; - struct st_select_lex *select; + SELECT_LEX *select; derived_handler(THD *thd_arg, handlerton *ht_arg) : thd(thd_arg), ht(ht_arg), derived(0),table(0), tmp_table_param(0), diff --git a/sql/select_handler.cc b/sql/select_handler.cc index f196678..da367f5 100644 --- a/sql/select_handler.cc +++ b/sql/select_handler.cc @@ -3,6 +3,13 @@ #include "sql_select.h" #include "select_handler.h" + +Pushdown_select::Pushdown_select(SELECT_LEX *sel, select_handler *h) + : select(sel), handler(h) +{ + is_analyze= handler->thd->lex->analyze_stmt; +} + Pushdown_select::~Pushdown_select() { delete handler; @@ -100,6 +107,12 @@ int Pushdown_select::execute() if ((err= handler->init_scan())) goto error; + if (is_analyze) + { + handler->end_scan(); + DBUG_RETURN(0); + } + if (send_result_set_metadata()) DBUG_RETURN(-1); diff --git a/sql/select_handler.h b/sql/select_handler.h index 68fca03..3b1347e 100644 --- a/sql/select_handler.h +++ b/sql/select_handler.h @@ -12,7 +12,7 @@ class select_handler SELECT_LEX *select; - /* + /* Temporary table where all results should be stored in record[0] The table has a field for every item from the select_lex::item_list. */ @@ -29,20 +29,20 @@ class select_handler */ /* Initialize the process of producing rows of result set */ - virtual int init_scan()= 0; + virtual int init_scan() = 0; /* Put the next produced row of the result set in table->record[0] and return 0. Return HA_ERR_END_OF_FILE if there are no more rows, return other error number in case of fatal error. */ - virtual int next_row()= 0; + virtual int next_row() = 0; /* Finish scanning */ - virtual int end_scan()=0; + virtual int end_scan() = 0; /* Report errors */ - virtual void print_error(int error, myf errflag)=0; + virtual void print_error(int error, myf errflag) = 0; }; #endif /* SELECT_HANDLER_INCLUDED */ diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 3f1dc80..b8d80c7 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -35,6 +35,7 @@ const char *unit_operation_text[4]= }; const char *pushed_derived_text= "PUSHED DERIVED"; +const char *pushed_select_text= "PUSHED SELECT"; static void write_item(Json_writer *writer, Item *item); static void append_item_to_str(String *out, Item *item); @@ -751,7 +752,7 @@ int Explain_select::print_explain(Explain_query *query, THD *thd= output->thd; MEM_ROOT *mem_root= thd->mem_root; - if (select_type == pushed_derived_text) + if (select_type == pushed_derived_text || select_type == pushed_select_text) { print_explain_message_line(output, explain_flags, is_analyze, select_id /*select number*/, @@ -882,7 +883,9 @@ void Explain_select::print_explain_json(Explain_query *query, bool started_cache= print_explain_json_cache(writer, is_analyze); - if (message || select_type == pushed_derived_text) + if (message || + select_type == pushed_derived_text || + select_type == pushed_select_text) { writer->add_member("query_block").start_object(); writer->add_member("select_id").add_ll(select_id); @@ -890,7 +893,10 @@ void Explain_select::print_explain_json(Explain_query *query, writer->add_member("table").start_object(); writer->add_member("message").add_str(select_type == pushed_derived_text ? - "Pushed derived" : message); + "Pushed derived" : + select_type == pushed_select_text ? + "Pushed select" : + message); writer->end_object(); print_explain_json_for_children(query, writer, is_analyze); diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 549b085..587ee53 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -329,6 +329,7 @@ class Explain_aggr_window_funcs : public Explain_aggr_node extern const char *unit_operation_text[4]; extern const char *pushed_derived_text; +extern const char *pushed_select_text; /* Explain structure for a UNION. diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 4c33091..87f50d4 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -4651,7 +4651,10 @@ void st_select_lex::set_explain_type(bool on_the_fly) if (master_unit()->thd->lex->first_select_lex() == this) { - type= is_primary ? "PRIMARY" : "SIMPLE"; + if (pushdown_select) + type= pushed_select_text; + else + type= is_primary ? "PRIMARY" : "SIMPLE"; } else { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4ac5ea1..2753f1a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1440,7 +1440,8 @@ int JOIN::optimize() join_optimization_state init_state= optimization_state; if (select_lex->pushdown_select) { - res= select_lex->pushdown_select->init(); + if (!(select_options & SELECT_DESCRIBE)) + res= select_lex->pushdown_select->init(); with_two_phase_optimization= false; } else if (optimization_state == JOIN::OPTIMIZATION_PHASE_1_DONE) @@ -3940,13 +3941,6 @@ void JOIN::exec_inner() if (select_options & SELECT_DESCRIBE) select_describe(this, FALSE, FALSE, FALSE, (zero_result_cause?zero_result_cause:"No tables used")); - - else if (select_lex->pushdown_select) - { - error= select_lex->pushdown_select->execute(); - delete select_lex->pushdown_select; - DBUG_VOID_RETURN; - } else { if (result->send_result_set_metadata(*columns_list, @@ -4071,12 +4065,18 @@ void JOIN::exec_inner() order != 0 && !skip_sort_order, select_distinct, !table_count ? "No tables used" : NullS); + if (select_lex->pushdown_select) + { + delete select_lex->pushdown_select; + select_lex->pushdown_select= NULL; + } DBUG_VOID_RETURN; } else if (select_lex->pushdown_select) { error= select_lex->pushdown_select->execute(); - delete select_lex->pushdown_select; + delete select_lex->pushdown_select; + select_lex->pushdown_select= NULL; DBUG_VOID_RETURN; } else @@ -4290,6 +4290,7 @@ mysql_select(THD *thd, } } +#if 1 select_lex->select_h= select_lex->find_select_handler(thd); if (select_lex->select_h) { @@ -4298,6 +4299,7 @@ mysql_select(THD *thd, select_lex->select_h))) DBUG_RETURN(TRUE); } +#endif if ((err= join->optimize())) { @@ -25748,6 +25750,13 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) first->options | thd->variables.option_bits | SELECT_DESCRIBE, result, unit, first); } + + if (unit->derived && unit->derived->pushdown_derived) + { + delete unit->derived->pushdown_derived; + unit->derived->pushdown_derived= NULL; + } + DBUG_RETURN(res || thd->is_error()); } diff --git a/sql/sql_select.h b/sql/sql_select.h index e9cf51b..bca2387 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -2449,12 +2449,13 @@ class derived_handler; class Pushdown_derived: public Sql_alloc { +private: + bool is_analyze; public: TABLE_LIST *derived; derived_handler *handler; - Pushdown_derived(TABLE_LIST *tbl, derived_handler *h) - : derived(tbl), handler(h) {} + Pushdown_derived(TABLE_LIST *tbl, derived_handler *h); ~Pushdown_derived(); @@ -2468,6 +2469,7 @@ class select_handler; class Pushdown_select: public Sql_alloc { private: + bool is_analyze; List<Item> result_columns; bool send_result_set_metadata(); bool send_data(); @@ -2477,8 +2479,7 @@ class Pushdown_select: public Sql_alloc SELECT_LEX *select; select_handler *handler; - Pushdown_select(SELECT_LEX *sel, select_handler *h) - : select(sel), handler(h) {} + Pushdown_select(SELECT_LEX *sel, select_handler *h); ~Pushdown_select(); diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index ec96a24..174ee23 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -3677,6 +3677,7 @@ int ha_federatedx::discover_assisted(handlerton *hton, THD* thd, return error; } + static derived_handler* create_federatedx_derived_handler(THD* thd, TABLE_LIST *derived) { @@ -3708,7 +3709,8 @@ create_federatedx_derived_handler(THD* thd, TABLE_LIST *derived) ha_federatedx_derived_handler::ha_federatedx_derived_handler(THD *thd, TABLE_LIST *dt) - : derived_handler(thd, federatedx_hton) + : derived_handler(thd, federatedx_hton), + share(NULL), txn(NULL), iop(NULL), stored_result(NULL) { derived= dt; } @@ -3725,24 +3727,21 @@ int ha_federatedx_derived_handler::init_scan() TABLE *table= derived->get_first_table()->table; ha_federatedx *h= (ha_federatedx *) table->file; - io= h->io; + iop= &h->io; share= get_share(table->s->table_name.str, table); thd= table->in_use; txn= h->get_txn(thd); - if ((rc= txn->acquire(share, thd, TRUE, &io))) + if ((rc= txn->acquire(share, thd, TRUE, iop))) DBUG_RETURN(rc); String derived_query(query_buff, sizeof(query_buff), thd->charset()); derived_query.length(0); derived->derived->print(&derived_query, QT_ORDINARY); - // if (stored_result) - // (void) free_result(); - - if (io->query(derived_query.ptr(), derived_query.length())) + if ((*iop)->query(derived_query.ptr(), derived_query.length())) goto err; - stored_result= io->store_result(); + stored_result= (*iop)->store_result(); if (!stored_result) goto err; @@ -3762,24 +3761,24 @@ int ha_federatedx_derived_handler::next_row() Time_zone *saved_time_zone= table->in_use->variables.time_zone; DBUG_ENTER("ha_federatedx_derived_handler::next_row"); - if ((rc= txn->acquire(share, table->in_use, TRUE, &io))) + if ((rc= txn->acquire(share, table->in_use, TRUE, iop))) DBUG_RETURN(rc); - if (!(row= io->fetch_row(stored_result))) + if (!(row= (*iop)->fetch_row(stored_result))) DBUG_RETURN(HA_ERR_END_OF_FILE); /* Convert row to internal format */ table->in_use->variables.time_zone= UTC; - lengths= io->fetch_lengths(stored_result); + lengths= (*iop)->fetch_lengths(stored_result); for (field= table->field; *field; field++, column++) { - if (io->is_column_null(row, column)) + if ((*iop)->is_column_null(row, column)) (*field)->set_null(); else { (*field)->set_notnull(); - (*field)->store(io->get_column_data(row, column), + (*field)->store((*iop)->get_column_data(row, column), lengths[column], &my_charset_bin); } } @@ -3791,6 +3790,11 @@ int ha_federatedx_derived_handler::next_row() int ha_federatedx_derived_handler::end_scan() { DBUG_ENTER("ha_federatedx_derived_handler::end_scan"); + + (*iop)->free_result(stored_result); + + free_share(txn, share); + DBUG_RETURN(0); } @@ -3822,7 +3826,8 @@ create_federatedx_select_handler(THD* thd, SELECT_LEX *sel) ha_federatedx_select_handler::ha_federatedx_select_handler(THD *thd, SELECT_LEX *sel) - : select_handler(thd, federatedx_hton) + : select_handler(thd, federatedx_hton), + share(NULL), txn(NULL), iop(NULL), stored_result(NULL) { select= sel; } @@ -3844,16 +3849,16 @@ int ha_federatedx_select_handler::init_scan() break; } ha_federatedx *h= (ha_federatedx *) table->file; - io= h->io; + iop= &h->io; share= get_share(table->s->table_name.str, table); txn= h->get_txn(thd); - if ((rc= txn->acquire(share, thd, TRUE, &io))) + if ((rc= txn->acquire(share, thd, TRUE, iop))) DBUG_RETURN(rc); - if (io->query(thd->query(), thd->query_length())) + if ((*iop)->query(thd->query(), thd->query_length())) goto err; - stored_result= io->store_result(); + stored_result= (*iop)->store_result(); if (!stored_result) goto err; @@ -3865,7 +3870,7 @@ int ha_federatedx_select_handler::init_scan() int ha_federatedx_select_handler::next_row() { - int rc; + int rc= 0; FEDERATEDX_IO_ROW *row; ulong *lengths; Field **field; @@ -3873,24 +3878,24 @@ int ha_federatedx_select_handler::next_row() Time_zone *saved_time_zone= table->in_use->variables.time_zone; DBUG_ENTER("ha_federatedx_select_handler::next_row"); - if ((rc= txn->acquire(share, table->in_use, TRUE, &io))) + if ((rc= txn->acquire(share, table->in_use, TRUE, iop))) DBUG_RETURN(rc); - if (!(row= io->fetch_row(stored_result))) + if (!(row= (*iop)->fetch_row(stored_result))) DBUG_RETURN(HA_ERR_END_OF_FILE); /* Convert row to internal format */ table->in_use->variables.time_zone= UTC; - lengths= io->fetch_lengths(stored_result); + lengths= (*iop)->fetch_lengths(stored_result); for (field= table->field; *field; field++, column++) { - if (io->is_column_null(row, column)) + if ((*iop)->is_column_null(row, column)) (*field)->set_null(); else { (*field)->set_notnull(); - (*field)->store(io->get_column_data(row, column), + (*field)->store((*iop)->get_column_data(row, column), lengths[column], &my_charset_bin); } } @@ -3906,8 +3911,9 @@ int ha_federatedx_select_handler::end_scan() free_tmp_table(thd, table); table= 0; - txn->release(&io); - DBUG_ASSERT(io == NULL); + (*iop)->free_result(stored_result); + + free_share(txn, share); DBUG_RETURN(0); } diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h index 4c721e5..3a5180f 100644 --- a/storage/federatedx/ha_federatedx.h +++ b/storage/federatedx/ha_federatedx.h @@ -468,12 +468,13 @@ extern federatedx_io *instantiate_io_mysql(MEM_ROOT *server_root, extern federatedx_io *instantiate_io_null(MEM_ROOT *server_root, FEDERATEDX_SERVER *server); + class ha_federatedx_derived_handler: public derived_handler { private: FEDERATEDX_SHARE *share; federatedx_txn *txn; - federatedx_io *io; + federatedx_io **iop; FEDERATEDX_IO_RESULT *stored_result; public: @@ -491,7 +492,7 @@ class ha_federatedx_select_handler: public select_handler private: FEDERATEDX_SHARE *share; federatedx_txn *txn; - federatedx_io *io; + federatedx_io **iop; FEDERATEDX_IO_RESULT *stored_result; public:
participants (1)
-
IgorBabaev