diff options
-rw-r--r-- | sql/group_by_handler.cc | 22 | ||||
-rw-r--r-- | sql/group_by_handler.h | 29 | ||||
-rw-r--r-- | sql/handler.h | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 33 | ||||
-rw-r--r-- | sql/sql_select.h | 21 | ||||
-rw-r--r-- | storage/sequence/sequence.cc | 24 |
6 files changed, 65 insertions, 67 deletions
diff --git a/sql/group_by_handler.cc b/sql/group_by_handler.cc index ba798967d34..ce73b1c3512 100644 --- a/sql/group_by_handler.cc +++ b/sql/group_by_handler.cc @@ -35,15 +35,17 @@ -1 if error should be sent */ -int group_by_handler::execute(JOIN *join) +int Pushdown_query::execute(JOIN *join) { int err; ha_rows max_limit; ha_rows *reset_limit= 0; Item **reset_item= 0; - DBUG_ENTER("group_by_handler::execute"); + THD *thd= handler->thd; + TABLE *table= handler->table; + DBUG_ENTER("Pushdown_query::execute"); - if ((err= init_scan())) + if ((err= handler->init_scan())) goto error; if (store_data_in_temp_table) @@ -58,17 +60,17 @@ int group_by_handler::execute(JOIN *join) reset_item= &join->unit->fake_select_lex->select_limit; } - while (!(err= next_row())) + while (!(err= handler->next_row())) { if (thd->check_killed()) { thd->send_kill_message(); - (void) end_scan(); + handler->end_scan(); DBUG_RETURN(-1); } /* Check if we can accept the row */ - if (!having || having->val_bool()) + if (!handler->having || handler->having->val_bool()) { if (store_data_in_temp_table) { @@ -97,7 +99,7 @@ int group_by_handler::execute(JOIN *join) /* result < 0 if row was not accepted and should not be counted */ if ((error= join->result->send_data(*join->fields))) { - (void) end_scan(); + handler->end_scan(); DBUG_RETURN(error < 0 ? 0 : -1); } } @@ -119,7 +121,7 @@ int group_by_handler::execute(JOIN *join) if (err != 0 && err != HA_ERR_END_OF_FILE) goto error; - if ((err= end_scan())) + if ((err= handler->end_scan())) goto error_2; if (!store_data_in_temp_table && join->result->send_eof()) DBUG_RETURN(1); // Don't send error to client @@ -127,9 +129,9 @@ int group_by_handler::execute(JOIN *join) DBUG_RETURN(0); error: - (void) end_scan(); + handler->end_scan(); error_2: - print_error(err, MYF(0)); + handler->print_error(err, MYF(0)); DBUG_RETURN(-1); // Error not sent to client } diff --git a/sql/group_by_handler.h b/sql/group_by_handler.h index 2187ee0848e..207e90e73c9 100644 --- a/sql/group_by_handler.h +++ b/sql/group_by_handler.h @@ -18,7 +18,7 @@ This file implements the group_by_handler interface. This interface can be used by storage handlers that can intercept summary or GROUP BY queries from MariaDB and itself return the result to the user or - upper level. + upper level. It is part of the Storage Engine API Both main and sub queries are supported. Here are some examples of what the storage engine could intersept: @@ -30,35 +30,26 @@ SELECT a, (select sum(*) from t2 where t1.a=t2.a) from t2; */ -class JOIN; - class group_by_handler { public: - /* Arguments for group_by_handler, for usage later */ THD *thd; - SELECT_LEX *select_lex; List<Item> *fields; TABLE_LIST *table_list; ORDER *group_by, *order_by; Item *where, *having; - handlerton *ht; /* storage engine of this handler */ + handlerton *ht; /* Temporary table where all results should be stored in record[0] */ TABLE *table; - bool store_data_in_temp_table; /* Set by mariadb */ - - group_by_handler(THD *thd_arg, SELECT_LEX *select_lex_arg, - List<Item> *fields_arg, + group_by_handler(THD *thd_arg, List<Item> *fields_arg, TABLE_LIST *table_list_arg, ORDER *group_by_arg, - ORDER *order_by_arg, Item *where_arg, - Item *having_arg, handlerton *ht_arg) - : thd(thd_arg), select_lex(select_lex_arg), fields(fields_arg), - table_list(table_list_arg), group_by(group_by_arg), - order_by(order_by_arg), where(where_arg), having(having_arg), - ht(ht_arg), table(0), store_data_in_temp_table(0) - {} + ORDER *order_by_arg, Item *where_arg, Item *having_arg, + handlerton *ht_arg) + : thd(thd_arg), fields(fields_arg), table_list(table_list_arg), + group_by(group_by_arg), order_by(order_by_arg), where(where_arg), + having(having_arg), ht(ht_arg), table(0) {} virtual ~group_by_handler() {} /* @@ -118,9 +109,7 @@ public: /* End scanning */ virtual int end_scan()=0; - /* Function that calls the above scan functions */ - int execute(JOIN *join); - /* Report errors */ virtual void print_error(int error, myf errflag); }; + diff --git a/sql/handler.h b/sql/handler.h index a0c9855cfde..fb5ce226a74 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1267,8 +1267,7 @@ struct handlerton The server guaranteeds that all tables in the list belong to this storage engine. */ - group_by_handler *(*create_group_by)(THD *thd, SELECT_LEX *select_lex, - List<Item> *fields, + group_by_handler *(*create_group_by)(THD *thd, List<Item> *fields, TABLE_LIST *table_list, ORDER *group_by, ORDER *order_by, Item *where, Item *having); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 86738350f50..5307b4b8f52 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1918,14 +1918,12 @@ JOIN::optimize_inner() (one_storage_engine && one_storage_engine->create_group_by)) { /* Check if the storage engine can intercept the query */ - if ((storage_handler_for_group_by= - (one_storage_engine->create_group_by)(thd, select_lex, - &all_fields, - tables_list, - group_list, order, - conds, having))) - { - uint handler_flags= storage_handler_for_group_by->flags(); + group_by_handler *gbh= one_storage_engine->create_group_by(thd, &all_fields, + tables_list, group_list, order, conds, having); + if (gbh) + { + pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, gbh); + uint handler_flags= gbh->flags(); int err; /* @@ -1962,13 +1960,13 @@ JOIN::optimize_inner() DBUG_RETURN(1); /* Give storage engine access to temporary table */ - if ((err= storage_handler_for_group_by->init(exec_tmp_table1, + if ((err= gbh->init(exec_tmp_table1, having, order))) { - storage_handler_for_group_by->print_error(err, MYF(0)); + gbh->print_error(err, MYF(0)); DBUG_RETURN(1); } - storage_handler_for_group_by->store_data_in_temp_table= need_tmp; + pushdown_query->store_data_in_temp_table= need_tmp; /* If no ORDER BY clause was specified explicitly, we should sort things according to the group_by @@ -2082,7 +2080,7 @@ int JOIN::init_execution() thd->lex->set_limit_rows_examined(); /* Create a tmp table if distinct or if the sort is too complicated */ - if (need_tmp && ! storage_handler_for_group_by) + if (need_tmp && !pushdown_query) { DBUG_PRINT("info",("Creating tmp table")); THD_STAGE_INFO(thd, stage_copying_to_tmp_table); @@ -12053,8 +12051,8 @@ void JOIN::cleanup(bool full) } tmp_table_param.cleanup(); - delete storage_handler_for_group_by; - storage_handler_for_group_by= 0; + delete pushdown_query; + pushdown_query= 0; if (!join_tab) { @@ -17854,15 +17852,14 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) join->fields= fields; join->do_select_call_count++; - if (join->storage_handler_for_group_by && - join->do_select_call_count == 1) + if (join->pushdown_query && join->do_select_call_count == 1) { /* Select fields are in the temporary table */ join->fields= &join->tmp_fields_list1; /* Setup HAVING to work with fields in temporary table */ join->set_items_ref_array(join->items1); /* The storage engine will take care of the group by query result */ - int res= join->storage_handler_for_group_by->execute(join); + int res= join->pushdown_query->execute(join); DBUG_RETURN(res); } @@ -24330,7 +24327,7 @@ int JOIN::save_explain_data_intern(Explain_query *output, bool need_tmp_table, explain->connection_type= Explain_node::EXPLAIN_NODE_DERIVED; output->add_node(explain); } - else if (storage_handler_for_group_by) + else if (pushdown_query) { explain= new (output->mem_root) Explain_select(output->mem_root, thd->lex->analyze_stmt); diff --git a/sql/sql_select.h b/sql/sql_select.h index 4f07a51788a..79894742caa 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -884,6 +884,7 @@ public: JOIN_TAB *end; }; +class Pushdown_query; class JOIN :public Sql_alloc { @@ -1088,7 +1089,7 @@ public: /* points to a storage engine if all tables comes from the storage engine */ handlerton *one_storage_engine; - group_by_handler *storage_handler_for_group_by; + Pushdown_query *pushdown_query; JOIN_TAB *original_join_tab; uint original_table_count; @@ -1391,7 +1392,7 @@ public: no_rows_in_result_called= 0; positions= best_positions= 0; one_storage_engine= 0; - storage_handler_for_group_by= 0; + pushdown_query= 0; original_join_tab= 0; do_select_call_count= 0; @@ -1964,5 +1965,21 @@ ulong check_selectivity(THD *thd, TABLE *table, List<COND_STATISTIC> *conds); +class Pushdown_query: public Sql_alloc +{ +public: + SELECT_LEX *select_lex; + bool store_data_in_temp_table; + group_by_handler *handler; + + Pushdown_query(SELECT_LEX *select_lex_arg, group_by_handler *handler_arg) + : select_lex(select_lex_arg), store_data_in_temp_table(0), + handler(handler_arg) {} + + ~Pushdown_query() { delete handler; } + + /* Function that calls the above scan functions */ + int execute(JOIN *join); +}; #endif /* SQL_SELECT_INCLUDED */ diff --git a/storage/sequence/sequence.cc b/storage/sequence/sequence.cc index ba8e157c3e4..46dcd2f3296 100644 --- a/storage/sequence/sequence.cc +++ b/storage/sequence/sequence.cc @@ -362,15 +362,12 @@ class ha_seq_group_by_handler: public group_by_handler bool first_row; public: - ha_seq_group_by_handler(THD *thd, SELECT_LEX *select_lex, - List<Item> *fields, - TABLE_LIST *table_list, ORDER *group_by, - ORDER *order_by, Item *where, - Item *having) - :group_by_handler(thd, select_lex, fields, table_list, group_by, - order_by, where, having, sequence_hton) - { - } + ha_seq_group_by_handler(THD *thd_arg, List<Item> *fields_arg, + TABLE_LIST *table_list_arg, ORDER *group_by_arg, + ORDER *order_by_arg, Item *where_arg, + Item *having_arg) + :group_by_handler(thd_arg, fields_arg, table_list_arg, group_by_arg, + order_by_arg, where_arg, having_arg, sequence_hton) {} ~ha_seq_group_by_handler() {} bool init(TABLE *temporary_table, Item *having_arg, ORDER *order_by_arg); @@ -380,10 +377,8 @@ public: }; static group_by_handler * -create_group_by_handler(THD *thd, SELECT_LEX *select_lex, - List<Item> *fields, - TABLE_LIST *table_list, ORDER *group_by, - ORDER *order_by, Item *where, +create_group_by_handler(THD *thd, List<Item> *fields, TABLE_LIST *table_list, + ORDER *group_by, ORDER *order_by, Item *where, Item *having) { ha_seq_group_by_handler *handler; @@ -432,8 +427,7 @@ create_group_by_handler(THD *thd, SELECT_LEX *select_lex, } /* Create handler and return it */ - handler= new ha_seq_group_by_handler(thd, select_lex, fields, table_list, - group_by, + handler= new ha_seq_group_by_handler(thd, fields, table_list, group_by, order_by, where, having); return handler; } |