summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-10-02 18:40:38 +0200
committerSergei Golubchik <serg@mariadb.org>2015-10-05 17:14:15 +0200
commit21175bb31610cdfe7f25b981edc760e46aa08c43 (patch)
treea9ec787cc2feebf6e93e112468c693dec441e575 /sql
parent8dff1aa5dc3335587b64ebf52ef2f8d5af2a0488 (diff)
downloadmariadb-git-21175bb31610cdfe7f25b981edc760e46aa08c43.tar.gz
Don't use flags in the group_by_handler class
instead pass the whole query down and let the engine return unsupported parts back
Diffstat (limited to 'sql')
-rw-r--r--sql/group_by_handler.h46
-rw-r--r--sql/handler.h6
-rw-r--r--sql/sql_select.cc27
3 files changed, 42 insertions, 37 deletions
diff --git a/sql/group_by_handler.h b/sql/group_by_handler.h
index 534acc27ee2..993e94819a2 100644
--- a/sql/group_by_handler.h
+++ b/sql/group_by_handler.h
@@ -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)
@@ -68,19 +99,6 @@ public:
}
/*
- 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
*/
diff --git a/sql/handler.h b/sql/handler.h
index fb5ce226a74..cfb6836f6d4 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -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.
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index dcd8bd839b2..af8571fb714 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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);
/*
@@ -1966,15 +1961,10 @@ 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;