Commit ebeb4f93 authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

MDEV-16327: Server doesn't account for engines that supports OFFSET on their own.

Engine get LIMIT/OFFSET info an can it use/reset.
parent a6de6408
......@@ -14,6 +14,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
#ifndef GROUP_BY_HANDLER_INCLUDED
#define GROUP_BY_HANDLER_INCLUDED
class Select_limit_counters;
/*
This file implements the group_by_handler interface. This interface
can be used by storage handlers that can intercept summary or GROUP
......@@ -56,7 +60,7 @@ struct Query
ORDER *order_by;
Item *having;
// LIMIT
//ha_rows select_limit_cnt, offset_limit_cnt;
Select_limit_counters *limit;
};
class group_by_handler
......@@ -101,3 +105,4 @@ class group_by_handler
virtual void print_error(int error, myf errflag);
};
#endif //GROUP_BY_HANDLER_INCLUDED
......@@ -28,6 +28,10 @@ class Select_limit_counters
Select_limit_counters():
select_limit_cnt(0), offset_limit_cnt(0)
{};
Select_limit_counters(Select_limit_counters &orig):
select_limit_cnt(orig.select_limit_cnt),
offset_limit_cnt(orig.offset_limit_cnt)
{};
void set_limit(ha_rows limit, ha_rows offset)
{
......@@ -48,6 +52,8 @@ class Select_limit_counters
bool is_unlimited()
{ return select_limit_cnt == HA_POS_ERROR; }
bool is_unrestricted()
{ return select_limit_cnt == HA_POS_ERROR && offset_limit_cnt == 0; }
void set_unlimited()
{ select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; }
......
......@@ -3146,7 +3146,8 @@ bool JOIN::make_aggr_tables_info()
{
/* Check if the storage engine can intercept the query */
Query query= {&all_fields, select_distinct, tables_list, conds,
group_list, order ? order : group_list, having};
group_list, order ? order : group_list, having,
&select_lex->master_unit()->lim};
group_by_handler *gbh= ht->create_group_by(thd, &query);
if (gbh)
......
......@@ -103,3 +103,33 @@ count(NULL)
select count(NULL) from seq_1_to_3 limit 0;
count(NULL)
# End of 10.3 tests
#
# MDEV-16327: Server doesn't account for engines that supports
# OFFSET on their own.
#
select count(NULL) from seq_1_to_3 limit 1;
count(NULL)
0
explain format=json select count(NULL) from seq_1_to_3 limit 1;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"message": "Storage engine handles GROUP BY"
}
}
}
select count(NULL) from seq_1_to_3 limit 1 offset 1;
count(NULL)
explain format=json select count(NULL) from seq_1_to_3 limit 1 offset 1;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"message": "Storage engine handles GROUP BY"
}
}
}
# End of 10.5 tests
......@@ -56,3 +56,15 @@ select count(NULL) from seq_1_to_3;
select count(NULL) from seq_1_to_3 limit 0;
--echo # End of 10.3 tests
--echo #
--echo # MDEV-16327: Server doesn't account for engines that supports
--echo # OFFSET on their own.
--echo #
select count(NULL) from seq_1_to_3 limit 1;
explain format=json select count(NULL) from seq_1_to_3 limit 1;
select count(NULL) from seq_1_to_3 limit 1 offset 1;
explain format=json select count(NULL) from seq_1_to_3 limit 1 offset 1;
--echo # End of 10.5 tests
......@@ -28,6 +28,7 @@
#include <handler.h>
#include <table.h>
#include <field.h>
#include <sql_limit.h>
static handlerton *sequence_hton;
......@@ -361,15 +362,21 @@ static int dummy_savepoint(handlerton *, THD *, void *) { return 0; }
class ha_seq_group_by_handler: public group_by_handler
{
Select_limit_counters limit;
List<Item> *fields;
TABLE_LIST *table_list;
bool first_row;
public:
ha_seq_group_by_handler(THD *thd_arg, List<Item> *fields_arg,
TABLE_LIST *table_list_arg)
: group_by_handler(thd_arg, sequence_hton), fields(fields_arg),
table_list(table_list_arg) {}
TABLE_LIST *table_list_arg,
Select_limit_counters *orig_lim)
: group_by_handler(thd_arg, sequence_hton), limit(orig_lim[0]),
fields(fields_arg), table_list(table_list_arg)
{
// Reset limit because we are handling it now
orig_lim->set_unlimited();
}
~ha_seq_group_by_handler() {}
int init_scan() { first_row= 1 ; return 0; }
int next_row();
......@@ -425,7 +432,8 @@ create_group_by_handler(THD *thd, Query *query)
}
/* Create handler and return it */
handler= new ha_seq_group_by_handler(thd, query->select, query->from);
handler= new ha_seq_group_by_handler(thd, query->select, query->from,
query->limit);
return handler;
}
......@@ -440,7 +448,9 @@ int ha_seq_group_by_handler::next_row()
Check if this is the first call to the function. If not, we have already
returned all data.
*/
if (!first_row)
if (!first_row ||
limit.get_offset_limit() > 0 ||
limit.get_select_limit() == 0)
DBUG_RETURN(HA_ERR_END_OF_FILE);
first_row= 0;
......
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