Commit 21175bb3 authored by Sergei Golubchik's avatar Sergei Golubchik

Don't use flags in the group_by_handler class

instead pass the whole query down and let the engine return
unsupported parts back
parent 8dff1aa5
......@@ -30,13 +30,44 @@
SELECT a, (select sum(*) from t2 where t1.a=t2.a) from t2;
*/
/**
The structure describing various parts of the query
The engine is supposed to take out parts that it can do internally.
For example, if the engine can return results sorted according to
the specified order_by clause, it sets Query::order_by=NULL before
returning.
At the moment the engine must take group_by (or return an error), and
optionally can take distinct, where, order_by, and having.
The engine should not modify the select list. It is the extended SELECT
clause (extended, because it has more items than the original
user-specified SELECT clause) and it contains all aggregate functions,
used in the query.
*/
struct Query
{
List<Item> *select;
bool distinct;
TABLE_LIST *from;
Item *where;
ORDER *group_by;
ORDER *order_by;
Item *having;
// LIMIT
};
class group_by_handler
{
public:
THD *thd;
handlerton *ht;
/* Temporary table where all results should be stored in record[0] */
/*
Temporary table where all results should be stored in record[0]
The table has a field for every item from the Query::select list.
*/
TABLE *table;
group_by_handler(THD *thd_arg, handlerton *ht_arg)
......@@ -67,19 +98,6 @@ public:
return init(having_arg, order_by_arg);
}
/*
Bits of things the storage engine can do for this query.
Should be initialized on object creation.
Result data is sorted by the storage engine according to order_by (if it
exists) else according to the group_by. If this is not specified,
MariaDB will store the result set into the temporary table and sort the
result.
*/
#define GROUP_BY_ORDER_BY 1
/* The storage engine can handle DISTINCT */
#define GROUP_BY_DISTINCT 2
virtual uint flags() { return 0; }
/*
Functions to scan data. All these returns 0 if ok, error code in case
of error
......
......@@ -950,6 +950,7 @@ struct handler_iterator {
class handler;
class group_by_handler;
struct Query;
typedef class st_select_lex SELECT_LEX;
typedef struct st_order ORDER;
......@@ -1267,10 +1268,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, List<Item> *fields,
TABLE_LIST *table_list, ORDER *group_by,
ORDER *order_by, Item *where,
Item *having);
group_by_handler *(*create_group_by)(THD *thd, Query *query);
/*********************************************************************
Table discovery API.
......
......@@ -1916,31 +1916,26 @@ JOIN::optimize_inner()
if (ht && ht->create_group_by)
{
/* Check if the storage engine can intercept the query */
group_by_handler *gbh= ht->create_group_by(thd, &all_fields,
tables_list, group_list, order, conds, having);
Query query= {&all_fields, select_distinct, tables_list, conds,
group_list, order ? order : group_list, having};
group_by_handler *gbh= ht->create_group_by(thd, &query);
if (gbh)
{
pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, gbh);
uint handler_flags= gbh->flags();
int err;
/*
We must store rows in the tmp table if we need to do an ORDER BY
or DISTINCT and the storage handler can't handle it.
*/
need_tmp= ((!(handler_flags & GROUP_BY_ORDER_BY) &&
(order || group_list)) ||
(!(handler_flags & GROUP_BY_DISTINCT) && select_distinct));
need_tmp= query.order_by || query.group_by || query.distinct;
tmp_table_param.hidden_field_count= (all_fields.elements -
fields_list.elements);
if (!(exec_tmp_table1=
create_tmp_table(thd, &tmp_table_param, all_fields, 0,
handler_flags & GROUP_BY_DISTINCT ?
0 : select_distinct, 1,
query.distinct, 1,
select_options, HA_POS_ERROR, "",
!need_tmp,
(!order ||
(handler_flags & GROUP_BY_ORDER_BY)))))
!need_tmp, query.order_by || query.group_by)))
DBUG_RETURN(1);
/*
......@@ -1965,16 +1960,11 @@ JOIN::optimize_inner()
}
pushdown_query->store_data_in_temp_table= need_tmp;
pushdown_query->having= having;
/*
If no ORDER BY clause was specified explicitly, we should sort things
according to the group_by
*/
if (!order)
order= group_list;
/*
Group by and having is calculated by the group_by handler.
Reset the group by and having
*/
DBUG_ASSERT(query.group_by == NULL);
group= 0; group_list= 0;
having= tmp_having= 0;
/*
......@@ -1982,8 +1972,7 @@ JOIN::optimize_inner()
over all fields in the temporary table
*/
select_distinct= 0;
if (handler_flags & GROUP_BY_ORDER_BY)
order= 0;
order= query.order_by;
tmp_table_param.field_count+= tmp_table_param.sum_func_count;
tmp_table_param.sum_func_count= 0;
......
......@@ -375,19 +375,17 @@ public:
};
static group_by_handler *
create_group_by_handler(THD *thd, List<Item> *fields, TABLE_LIST *table_list,
ORDER *group_by, ORDER *order_by, Item *where,
Item *having)
create_group_by_handler(THD *thd, Query *query)
{
ha_seq_group_by_handler *handler;
Item *item;
List_iterator_fast<Item> it(*fields);
List_iterator_fast<Item> it(*query->select);
/* check that only one table is used in FROM clause and no sub queries */
if (table_list->next_local != 0)
if (query->from->next_local != 0)
return 0;
/* check that there is no where clause and no group_by */
if (where != 0 || group_by != 0)
if (query->where != 0 || query->group_by != 0)
return 0;
/*
......@@ -417,7 +415,7 @@ create_group_by_handler(THD *thd, List<Item> *fields, TABLE_LIST *table_list,
Check that we are using the sequence table (the only table in the FROM
clause) and not an outer table.
*/
if (field->table != table_list->table)
if (field->table != query->from->table)
return 0;
/* Check that we are using a SUM() on the primary key */
if (strcmp(field->field_name, "seq"))
......@@ -425,7 +423,7 @@ create_group_by_handler(THD *thd, List<Item> *fields, TABLE_LIST *table_list,
}
/* Create handler and return it */
handler= new ha_seq_group_by_handler(thd, fields, table_list);
handler= new ha_seq_group_by_handler(thd, query->select, query->from);
return handler;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment