summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/group_by_handler.cc22
-rw-r--r--sql/group_by_handler.h29
-rw-r--r--sql/handler.h3
-rw-r--r--sql/sql_select.cc33
-rw-r--r--sql/sql_select.h21
-rw-r--r--storage/sequence/sequence.cc24
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;
}