[Commits] d11be23: MDEV-17096 Pushdown of simple derived tables to storage engines
revision-id: d11be23933def394585fae83a6f1ab561e3736f2 (mariadb-10.3.6-132-gd11be23) parent(s): 3f9040085a0de4976f55bc7e4a2fa5fa8d923100 author: Igor Babaev committer: Igor Babaev timestamp: 2019-02-09 22:54:26 -0800 message: MDEV-17096 Pushdown of simple derived tables to storage engines Resolved the problem of forming a proper query string for FEDERATEDX. Added test cases. Cleanup of extra spaces. --- .../federated/federatedx_create_handlers.result | 119 +++++++++++++++++++-- .../federated/federatedx_create_handlers.test | 60 +++++++++-- sql/derived_handler.cc | 8 +- sql/item_cmpfunc.cc | 9 +- sql/item_subselect.cc | 6 +- sql/mysqld.h | 2 + sql/select_handler.cc | 14 +-- sql/select_handler.h | 10 +- sql/sql_derived.cc | 34 ++++-- sql/sql_explain.cc | 6 +- sql/sql_select.cc | 8 +- sql/table.h | 1 + storage/federatedx/federatedx_pushdown.cc | 19 ++-- storage/federatedx/federatedx_pushdown.h | 4 +- 14 files changed, 233 insertions(+), 67 deletions(-) diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result index fdad44c..a25b019 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.result +++ b/mysql-test/suite/federated/federatedx_create_handlers.result @@ -10,7 +10,7 @@ Warnings: Note 1051 Unknown table 'federated.t1' CREATE TABLE federated.t1 ( id int(20) NOT NULL, -name varchar(16) NOT NULL default '' +name varchar(16) NOT NULL default '' ) DEFAULT CHARSET=latin1; INSERT INTO federated.t1 VALUES @@ -19,7 +19,7 @@ DROP TABLE IF EXISTS federated.t2; Warnings: Note 1051 Unknown table 'federated.t2' CREATE TABLE federated.t2 ( -name varchar(16) NOT NULL default '' +name varchar(16) NOT NULL default '' ) DEFAULT CHARSET=latin1; INSERT INTO federated.t2 VALUES @@ -30,7 +30,7 @@ Warnings: Note 1051 Unknown table 'federated.t1' CREATE TABLE federated.t1 ( id int(20) NOT NULL, -name varchar(16) NOT NULL default '' +name varchar(16) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; @@ -38,7 +38,7 @@ DROP TABLE IF EXISTS federated.t2; Warnings: Note 1051 Unknown table 'federated.t2' CREATE TABLE federated.t2 ( -name varchar(16) NOT NULL default '' +name varchar(16) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t2'; @@ -123,7 +123,7 @@ ANALYZE } } CREATE TABLE federated.t3 ( -name varchar(16) NOT NULL default '' +name varchar(16) NOT NULL default '' ) DEFAULT CHARSET=latin1; INSERT INTO federated.t3 VALUES @@ -190,7 +190,114 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f 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; +SELECT * +FROM federated.t3, (SELECT t1.name FROM federated.t1 +WHERE id IN (SELECT count(*) +FROM federated.t2 GROUP BY name)) t +WHERE federated.t3.name=t.name; +name name +xxx xxx +EXPLAIN +SELECT * +FROM federated.t3, (SELECT t1.name FROM federated.t1 +WHERE id IN (SELECT count(*) +FROM federated.t2 GROUP BY name)) 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 +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 Using temporary +ANALYZE FORMAT=JSON +SELECT * +FROM federated.t3, (SELECT t1.name FROM federated.t1 +WHERE id IN (SELECT count(*) +FROM federated.t2 GROUP BY name)) t +WHERE federated.t3.name=t.name; +ANALYZE +{ + "query_block": { + "select_id": 1, + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "table": { + "table_name": "t3", + "access_type": "ALL", + "r_loops": 1, + "rows": 7, + "r_rows": 7, + "r_total_time_ms": "REPLACED", + "filtered": 100, + "r_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"], + "r_loops": 7, + "rows": 2, + "r_rows": 0, + "r_total_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "table": { + "message": "Pushed derived" + }, + "subqueries": [ + { + "query_block": { + "select_id": 3, + "temporary_table": { + "table": { + "table_name": "t2", + "access_type": "ALL", + "r_loops": 0, + "rows": 7, + "r_rows": null, + "filtered": 100, + "r_filtered": null + } + } + } + } + ] + } + } + } + } +} +SELECT t.id, federated.t3.name +FROM federated.t3, +( SELECT * FROM federated.t1 WHERE id < 3 +UNION +SELECT * FROM federated.t1 WHERE id >= 5) t +WHERE federated.t3.name=t.name; +id name +5 yyy +7 yyy +5 yyy +7 yyy +5 yyy +7 yyy +EXPLAIN +SELECT t.id, federated.t3.name +FROM federated.t3, +( SELECT * FROM federated.t1 WHERE id < 3 +UNION +SELECT * FROM federated.t1 WHERE id >= 5) 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 +DROP TABLE federated.t1, federated.t2, federated.t3; 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 0e586da..21539b6 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.test +++ b/mysql-test/suite/federated/federatedx_create_handlers.test @@ -7,7 +7,7 @@ DROP TABLE IF EXISTS federated.t1; CREATE TABLE federated.t1 ( id int(20) NOT NULL, - name varchar(16) NOT NULL default '' + name varchar(16) NOT NULL default '' ) DEFAULT CHARSET=latin1; @@ -17,7 +17,7 @@ INSERT INTO federated.t1 VALUES DROP TABLE IF EXISTS federated.t2; CREATE TABLE federated.t2 ( - name varchar(16) NOT NULL default '' + name varchar(16) NOT NULL default '' ) DEFAULT CHARSET=latin1; @@ -33,7 +33,7 @@ DROP TABLE IF EXISTS federated.t1; eval CREATE TABLE federated.t1 ( id int(20) NOT NULL, - name varchar(16) NOT NULL default '' + name varchar(16) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; @@ -43,7 +43,7 @@ DROP TABLE IF EXISTS federated.t2; --replace_result $SLAVE_MYPORT SLAVE_PORT eval CREATE TABLE federated.t2 ( - name varchar(16) NOT NULL default '' + name varchar(16) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t2'; @@ -76,11 +76,12 @@ SELECT id FROM federated.t1 WHERE id < 5; ANALYZE SELECT id FROM federated.t1 WHERE id < 5; +--source include/analyze-format.inc ANALYZE FORMAT=JSON SELECT id FROM federated.t1 WHERE id < 5; CREATE TABLE federated.t3 ( - name varchar(16) NOT NULL default '' + name varchar(16) NOT NULL default '' ) DEFAULT CHARSET=latin1; @@ -89,26 +90,63 @@ INSERT INTO federated.t3 VALUES SELECT * FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t -WHERE federated.t3.name=t.name; +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; +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; +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; +WHERE federated.t3.name=t.name; -DROP TABLE federated.t1, federated.t2; +SELECT * +FROM federated.t3, (SELECT t1.name FROM federated.t1 + WHERE id IN (SELECT count(*) + FROM federated.t2 GROUP BY name)) t +WHERE federated.t3.name=t.name; -connection slave; +EXPLAIN +SELECT * +FROM federated.t3, (SELECT t1.name FROM federated.t1 + WHERE id IN (SELECT count(*) + FROM federated.t2 GROUP BY name)) t +WHERE federated.t3.name=t.name; + +--source include/analyze-format.inc +ANALYZE FORMAT=JSON +SELECT * +FROM federated.t3, (SELECT t1.name FROM federated.t1 + WHERE id IN (SELECT count(*) + FROM federated.t2 GROUP BY name)) t +WHERE federated.t3.name=t.name; + +SELECT t.id, federated.t3.name +FROM federated.t3, + ( SELECT * FROM federated.t1 WHERE id < 3 + UNION + SELECT * FROM federated.t1 WHERE id >= 5) t +WHERE federated.t3.name=t.name; + +EXPLAIN +SELECT t.id, federated.t3.name +FROM federated.t3, + ( SELECT * FROM federated.t1 WHERE id < 3 + UNION + SELECT * FROM federated.t1 WHERE id >= 5) t +WHERE federated.t3.name=t.name; + + +DROP TABLE federated.t1, federated.t2, federated.t3; + +connection slave; DROP TABLE federated.t1, federated.t2; connection default; diff --git a/sql/derived_handler.cc b/sql/derived_handler.cc index 561c18a..1fa5e94 100644 --- a/sql/derived_handler.cc +++ b/sql/derived_handler.cc @@ -16,7 +16,7 @@ void derived_handler::set_derived(TABLE_LIST *tbl) Pushdown_derived::Pushdown_derived(TABLE_LIST *tbl, derived_handler *h) : derived(tbl), handler(h) -{ +{ is_analyze= handler->thd->lex->analyze_stmt; } @@ -42,7 +42,7 @@ int Pushdown_derived::execute() handler->end_scan(); DBUG_RETURN(0); } - + while (!(err= handler->next_row())) { if (unlikely(thd->check_killed())) @@ -50,7 +50,7 @@ int Pushdown_derived::execute() handler->end_scan(); DBUG_RETURN(-1); } - + if ((err= table->file->ha_write_tmp_row(table->record[0]))) { bool is_duplicate; @@ -81,4 +81,4 @@ int Pushdown_derived::execute() handler->print_error(err, MYF(0)); DBUG_RETURN(-1); // Error not sent to client } - + diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4cd6304..821f51f 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1215,8 +1215,13 @@ bool Item_in_optimizer::eval_not_null_tables(void *opt_arg) void Item_in_optimizer::print(String *str, enum_query_type query_type) { - restore_first_argument(); - Item_func::print(str, query_type); + if (query_type & QT_PARSABLE) + args[1]->print(str, query_type); + else + { + restore_first_argument(); + Item_func::print(str, query_type); + } } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 0ace59f..7aa2ed4 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -3272,7 +3272,8 @@ Item_in_subselect::select_in_like_transformer(JOIN *join) void Item_in_subselect::print(String *str, enum_query_type query_type) { - if (test_strategy(SUBS_IN_TO_EXISTS)) + if (test_strategy(SUBS_IN_TO_EXISTS) && + !(query_type & QT_PARSABLE)) str->append(STRING_WITH_LEN("<exists>")); else { @@ -3499,7 +3500,8 @@ Item_allany_subselect::select_transformer(JOIN *join) void Item_allany_subselect::print(String *str, enum_query_type query_type) { - if (test_strategy(SUBS_IN_TO_EXISTS)) + if (test_strategy(SUBS_IN_TO_EXISTS) && + !(query_type & QT_PARSABLE)) str->append(STRING_WITH_LEN("<exists>")); else { diff --git a/sql/mysqld.h b/sql/mysqld.h index 3d056fb..320dedc 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -745,6 +745,8 @@ enum enum_query_type /// SHOW CREATE {VIEW|PROCEDURE|FUNCTION} and other cases where the /// original representation is required, should set this flag. QT_ITEM_ORIGINAL_FUNC_NULLIF= (1 << 7), + /// good for parsing + QT_PARSABLE= (1 << 8), /// This value means focus on readability, not on ability to parse back, etc. QT_EXPLAIN= QT_TO_SYSTEM_CHARSET | diff --git a/sql/select_handler.cc b/sql/select_handler.cc index 17475f4..9a8d391 100644 --- a/sql/select_handler.cc +++ b/sql/select_handler.cc @@ -6,7 +6,7 @@ Pushdown_select::Pushdown_select(SELECT_LEX *sel, select_handler *h) : select(sel), handler(h) -{ +{ is_analyze= handler->thd->lex->analyze_stmt; } @@ -35,7 +35,7 @@ bool Pushdown_select::init() DBUG_RETURN(true); if (handler->table->fill_item_list(&result_columns)) DBUG_RETURN(true); - DBUG_RETURN(false); + DBUG_RETURN(false); } bool Pushdown_select::send_result_set_metadata() @@ -74,7 +74,7 @@ bool Pushdown_select::send_data() protocol->remove_last_row(); DBUG_RETURN(true); } - + thd->inc_sent_row_count(1); if (thd->vio_ok()) @@ -88,13 +88,13 @@ 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()) DBUG_RETURN(true); - ::my_eof(thd); + ::my_eof(thd); DBUG_RETURN(false); } @@ -113,10 +113,10 @@ int Pushdown_select::execute() handler->end_scan(); DBUG_RETURN(0); } - + if (send_result_set_metadata()) DBUG_RETURN(-1); - + while (!(err= handler->next_row())) { if (thd->check_killed() || send_data()) diff --git a/sql/select_handler.h b/sql/select_handler.h index 3b1347e..19a1883 100644 --- a/sql/select_handler.h +++ b/sql/select_handler.h @@ -20,9 +20,9 @@ class select_handler select_handler(THD *thd_arg, handlerton *ht_arg) : thd(thd_arg), ht(ht_arg), table(0) {} - - virtual ~select_handler() {} - + + virtual ~select_handler() {} + /* Functions to scan the select result set. All these returns 0 if ok, error code in case of error. @@ -32,7 +32,7 @@ class select_handler virtual int init_scan() = 0; /* - Put the next produced row of the result set in table->record[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. */ @@ -40,7 +40,7 @@ class select_handler /* Finish scanning */ virtual int end_scan() = 0; - + /* Report errors */ virtual void print_error(int error, myf errflag) = 0; }; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 9ad22dd..564049e 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -385,7 +385,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) DBUG_RETURN(FALSE); } - if ((derived->dt_handler= derived->find_derived_handler(thd))) + if (derived->dt_handler) { derived->change_refs_to_fields(); derived->set_materialized_derived(); @@ -820,6 +820,24 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) if (derived->is_derived() && derived->is_merged_derived()) first_select->mark_as_belong_to_derived(derived); + derived->dt_handler= derived->find_derived_handler(thd); + if (derived->dt_handler) + { + char query_buff[4096]; + String derived_query(query_buff, sizeof(query_buff), thd->charset()); + derived_query.length(0); + derived->derived->print(&derived_query, + enum_query_type(QT_VIEW_INTERNAL | + QT_ITEM_ORIGINAL_FUNC_NULLIF | + QT_PARSABLE)); + if (!thd->make_lex_string(&derived->derived_spec, + derived_query.ptr(), derived_query.length())) + { + delete derived->dt_handler; + derived->dt_handler= NULL; + } + } + exit: /* Hide "Unknown column" or "Unknown function" error */ if (derived->view) @@ -912,19 +930,17 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) DBUG_RETURN(FALSE); } - if (derived->is_materialized_derived() && !derived->dt_handler) - derived->dt_handler= derived->find_derived_handler(thd); - if (derived->dt_handler) + if (derived->is_materialized_derived() && derived->dt_handler) { if (!(derived->pushdown_derived= new (thd->mem_root) Pushdown_derived(derived, derived->dt_handler))) { delete derived->dt_handler; - derived->dt_handler= NULL; - DBUG_RETURN(1); + derived->dt_handler= NULL; + DBUG_RETURN(TRUE); } - } - + } + lex->current_select= first_select; if (unit->is_unit_op()) @@ -1136,7 +1152,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) if (unit->executed) DBUG_RETURN(FALSE); res= derived->pushdown_derived->execute(); - unit->executed= true; + unit->executed= true; delete derived->pushdown_derived; DBUG_RETURN(res); } diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index b8d80c7..7bb04fe 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -339,7 +339,7 @@ int print_explain_row(select_result_sink *result, if (!select_type[0]) return 0; - + item_list.push_back(new (mem_root) Item_int(thd, (int32) select_number), mem_root); item_list.push_back(new (mem_root) Item_string_sys(thd, select_type), @@ -756,7 +756,7 @@ int Explain_select::print_explain(Explain_query *query, { print_explain_message_line(output, explain_flags, is_analyze, select_id /*select number*/, - select_type, + select_type, NULL, /* rows */ NULL); } @@ -1225,7 +1225,7 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai { THD *thd= output->thd; MEM_ROOT *mem_root= thd->mem_root; - + List<Item> item_list; Item *item_null= new (mem_root) Item_null(thd); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7cbbdfe..e9040e1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4044,7 +4044,7 @@ void JOIN::exec_inner() not the case. */ if (exec_const_order_group_cond.elements && - !(select_options & SELECT_DESCRIBE) && + !(select_options & SELECT_DESCRIBE) && !select_lex->pushdown_select) { List_iterator_fast<Item> const_item_it(exec_const_order_group_cond); @@ -4300,7 +4300,7 @@ mysql_select(THD *thd, DBUG_RETURN(TRUE); } } - + if ((err= join->optimize())) { goto err; // 1 @@ -4322,7 +4322,7 @@ mysql_select(THD *thd, select_lex->where= join->conds_history; select_lex->having= join->having_history; } - + err: if (select_lex->pushdown_select) @@ -25885,7 +25885,7 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) res= unit->exec(); } } - else + else { thd->lex->current_select= first; unit->set_limit(unit->global_parameters()); diff --git a/sql/table.h b/sql/table.h index 7b88344..f7bcdaa 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2137,6 +2137,7 @@ struct TABLE_LIST bool is_derived_with_recursive_reference; bool block_handle_derived; derived_handler *dt_handler; + LEX_CSTRING derived_spec; Pushdown_derived *pushdown_derived; ST_SCHEMA_TABLE *schema_table; /* Information_schema table */ st_select_lex *schema_select_lex; diff --git a/storage/federatedx/federatedx_pushdown.cc b/storage/federatedx/federatedx_pushdown.cc index bfe421c..c53b359 100644 --- a/storage/federatedx/federatedx_pushdown.cc +++ b/storage/federatedx/federatedx_pushdown.cc @@ -38,14 +38,14 @@ create_federatedx_derived_handler(THD* thd, TABLE_LIST *derived) return 0; } } - + handler= new ha_federatedx_derived_handler(thd, derived); return handler; } -/* +/* Implementation class of the derived_handler interface for FEDERATEDX: class implementation */ @@ -62,7 +62,6 @@ ha_federatedx_derived_handler::~ha_federatedx_derived_handler() {} int ha_federatedx_derived_handler::init_scan() { - char query_buff[4096]; THD *thd; int rc= 0; @@ -76,12 +75,8 @@ int ha_federatedx_derived_handler::init_scan() txn= h->get_txn(thd); 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 ((*iop)->query(derived_query.ptr(), derived_query.length())) + + if ((*iop)->query(derived->derived_spec.str, derived->derived_spec.length)) goto err; stored_result= (*iop)->store_result(); @@ -93,7 +88,7 @@ int ha_federatedx_derived_handler::init_scan() err: DBUG_RETURN(HA_FEDERATEDX_ERROR_WITH_REMOTE_SYSTEM); } - + int ha_federatedx_derived_handler::next_row() { int rc; @@ -167,7 +162,7 @@ create_federatedx_select_handler(THD* thd, SELECT_LEX *sel) return handler; } -/* +/* Implementation class of the select_handler interface for FEDERATEDX: class implementation */ @@ -175,7 +170,7 @@ 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), - share(NULL), txn(NULL), iop(NULL), stored_result(NULL) + share(NULL), txn(NULL), iop(NULL), stored_result(NULL) { select= sel; } diff --git a/storage/federatedx/federatedx_pushdown.h b/storage/federatedx/federatedx_pushdown.h index 961571b..673abcf 100644 --- a/storage/federatedx/federatedx_pushdown.h +++ b/storage/federatedx/federatedx_pushdown.h @@ -17,7 +17,7 @@ #include "derived_handler.h" #include "select_handler.h" -/* +/* Implementation class of the derived_handler interface for FEDERATEDX: class declaration */ @@ -40,7 +40,7 @@ class ha_federatedx_derived_handler: public derived_handler }; -/* +/* Implementation class of the select_handler interface for FEDERATEDX: class declaration */
participants (1)
-
IgorBabaev