Skip to content

Commit 21175bb

Browse files
committed
Don't use flags in the group_by_handler class
instead pass the whole query down and let the engine return unsupported parts back
1 parent 8dff1aa commit 21175bb

File tree

4 files changed

+48
-45
lines changed

4 files changed

+48
-45
lines changed

sql/group_by_handler.h

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,44 @@
3030
SELECT a, (select sum(*) from t2 where t1.a=t2.a) from t2;
3131
*/
3232

33+
/**
34+
The structure describing various parts of the query
35+
36+
The engine is supposed to take out parts that it can do internally.
37+
For example, if the engine can return results sorted according to
38+
the specified order_by clause, it sets Query::order_by=NULL before
39+
returning.
40+
41+
At the moment the engine must take group_by (or return an error), and
42+
optionally can take distinct, where, order_by, and having.
43+
44+
The engine should not modify the select list. It is the extended SELECT
45+
clause (extended, because it has more items than the original
46+
user-specified SELECT clause) and it contains all aggregate functions,
47+
used in the query.
48+
*/
49+
struct Query
50+
{
51+
List<Item> *select;
52+
bool distinct;
53+
TABLE_LIST *from;
54+
Item *where;
55+
ORDER *group_by;
56+
ORDER *order_by;
57+
Item *having;
58+
// LIMIT
59+
};
60+
3361
class group_by_handler
3462
{
3563
public:
3664
THD *thd;
3765
handlerton *ht;
3866

39-
/* Temporary table where all results should be stored in record[0] */
67+
/*
68+
Temporary table where all results should be stored in record[0]
69+
The table has a field for every item from the Query::select list.
70+
*/
4071
TABLE *table;
4172

4273
group_by_handler(THD *thd_arg, handlerton *ht_arg)
@@ -67,19 +98,6 @@ class group_by_handler
6798
return init(having_arg, order_by_arg);
6899
}
69100

70-
/*
71-
Bits of things the storage engine can do for this query.
72-
Should be initialized on object creation.
73-
Result data is sorted by the storage engine according to order_by (if it
74-
exists) else according to the group_by. If this is not specified,
75-
MariaDB will store the result set into the temporary table and sort the
76-
result.
77-
*/
78-
#define GROUP_BY_ORDER_BY 1
79-
/* The storage engine can handle DISTINCT */
80-
#define GROUP_BY_DISTINCT 2
81-
virtual uint flags() { return 0; }
82-
83101
/*
84102
Functions to scan data. All these returns 0 if ok, error code in case
85103
of error

sql/handler.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,7 @@ struct handler_iterator {
950950

951951
class handler;
952952
class group_by_handler;
953+
struct Query;
953954
typedef class st_select_lex SELECT_LEX;
954955
typedef struct st_order ORDER;
955956

@@ -1267,10 +1268,7 @@ struct handlerton
12671268
The server guaranteeds that all tables in the list belong to this
12681269
storage engine.
12691270
*/
1270-
group_by_handler *(*create_group_by)(THD *thd, List<Item> *fields,
1271-
TABLE_LIST *table_list, ORDER *group_by,
1272-
ORDER *order_by, Item *where,
1273-
Item *having);
1271+
group_by_handler *(*create_group_by)(THD *thd, Query *query);
12741272

12751273
/*********************************************************************
12761274
Table discovery API.

sql/sql_select.cc

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,31 +1916,26 @@ JOIN::optimize_inner()
19161916
if (ht && ht->create_group_by)
19171917
{
19181918
/* Check if the storage engine can intercept the query */
1919-
group_by_handler *gbh= ht->create_group_by(thd, &all_fields,
1920-
tables_list, group_list, order, conds, having);
1919+
Query query= {&all_fields, select_distinct, tables_list, conds,
1920+
group_list, order ? order : group_list, having};
1921+
group_by_handler *gbh= ht->create_group_by(thd, &query);
19211922
if (gbh)
19221923
{
19231924
pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, gbh);
1924-
uint handler_flags= gbh->flags();
19251925
int err;
19261926

19271927
/*
19281928
We must store rows in the tmp table if we need to do an ORDER BY
19291929
or DISTINCT and the storage handler can't handle it.
19301930
*/
1931-
need_tmp= ((!(handler_flags & GROUP_BY_ORDER_BY) &&
1932-
(order || group_list)) ||
1933-
(!(handler_flags & GROUP_BY_DISTINCT) && select_distinct));
1931+
need_tmp= query.order_by || query.group_by || query.distinct;
19341932
tmp_table_param.hidden_field_count= (all_fields.elements -
19351933
fields_list.elements);
19361934
if (!(exec_tmp_table1=
19371935
create_tmp_table(thd, &tmp_table_param, all_fields, 0,
1938-
handler_flags & GROUP_BY_DISTINCT ?
1939-
0 : select_distinct, 1,
1936+
query.distinct, 1,
19401937
select_options, HA_POS_ERROR, "",
1941-
!need_tmp,
1942-
(!order ||
1943-
(handler_flags & GROUP_BY_ORDER_BY)))))
1938+
!need_tmp, query.order_by || query.group_by)))
19441939
DBUG_RETURN(1);
19451940

19461941
/*
@@ -1965,25 +1960,19 @@ JOIN::optimize_inner()
19651960
}
19661961
pushdown_query->store_data_in_temp_table= need_tmp;
19671962
pushdown_query->having= having;
1968-
/*
1969-
If no ORDER BY clause was specified explicitly, we should sort things
1970-
according to the group_by
1971-
*/
1972-
if (!order)
1973-
order= group_list;
19741963
/*
19751964
Group by and having is calculated by the group_by handler.
19761965
Reset the group by and having
19771966
*/
1967+
DBUG_ASSERT(query.group_by == NULL);
19781968
group= 0; group_list= 0;
19791969
having= tmp_having= 0;
19801970
/*
19811971
Select distinct is handled by handler or by creating an unique index
19821972
over all fields in the temporary table
19831973
*/
19841974
select_distinct= 0;
1985-
if (handler_flags & GROUP_BY_ORDER_BY)
1986-
order= 0;
1975+
order= query.order_by;
19871976
tmp_table_param.field_count+= tmp_table_param.sum_func_count;
19881977
tmp_table_param.sum_func_count= 0;
19891978

storage/sequence/sequence.cc

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -375,19 +375,17 @@ class ha_seq_group_by_handler: public group_by_handler
375375
};
376376

377377
static group_by_handler *
378-
create_group_by_handler(THD *thd, List<Item> *fields, TABLE_LIST *table_list,
379-
ORDER *group_by, ORDER *order_by, Item *where,
380-
Item *having)
378+
create_group_by_handler(THD *thd, Query *query)
381379
{
382380
ha_seq_group_by_handler *handler;
383381
Item *item;
384-
List_iterator_fast<Item> it(*fields);
382+
List_iterator_fast<Item> it(*query->select);
385383

386384
/* check that only one table is used in FROM clause and no sub queries */
387-
if (table_list->next_local != 0)
385+
if (query->from->next_local != 0)
388386
return 0;
389387
/* check that there is no where clause and no group_by */
390-
if (where != 0 || group_by != 0)
388+
if (query->where != 0 || query->group_by != 0)
391389
return 0;
392390

393391
/*
@@ -417,15 +415,15 @@ create_group_by_handler(THD *thd, List<Item> *fields, TABLE_LIST *table_list,
417415
Check that we are using the sequence table (the only table in the FROM
418416
clause) and not an outer table.
419417
*/
420-
if (field->table != table_list->table)
418+
if (field->table != query->from->table)
421419
return 0;
422420
/* Check that we are using a SUM() on the primary key */
423421
if (strcmp(field->field_name, "seq"))
424422
return 0;
425423
}
426424

427425
/* Create handler and return it */
428-
handler= new ha_seq_group_by_handler(thd, fields, table_list);
426+
handler= new ha_seq_group_by_handler(thd, query->select, query->from);
429427
return handler;
430428
}
431429

0 commit comments

Comments
 (0)