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 @@ ...@@ -14,6 +14,10 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ 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 This file implements the group_by_handler interface. This interface
can be used by storage handlers that can intercept summary or GROUP can be used by storage handlers that can intercept summary or GROUP
...@@ -56,7 +60,7 @@ struct Query ...@@ -56,7 +60,7 @@ struct Query
ORDER *order_by; ORDER *order_by;
Item *having; Item *having;
// LIMIT // LIMIT
//ha_rows select_limit_cnt, offset_limit_cnt; Select_limit_counters *limit;
}; };
class group_by_handler class group_by_handler
...@@ -101,3 +105,4 @@ class group_by_handler ...@@ -101,3 +105,4 @@ class group_by_handler
virtual void print_error(int error, myf errflag); virtual void print_error(int error, myf errflag);
}; };
#endif //GROUP_BY_HANDLER_INCLUDED
...@@ -28,6 +28,10 @@ class Select_limit_counters ...@@ -28,6 +28,10 @@ class Select_limit_counters
Select_limit_counters(): Select_limit_counters():
select_limit_cnt(0), offset_limit_cnt(0) 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) void set_limit(ha_rows limit, ha_rows offset)
{ {
...@@ -48,6 +52,8 @@ class Select_limit_counters ...@@ -48,6 +52,8 @@ class Select_limit_counters
bool is_unlimited() bool is_unlimited()
{ return select_limit_cnt == HA_POS_ERROR; } { return select_limit_cnt == HA_POS_ERROR; }
bool is_unrestricted()
{ return select_limit_cnt == HA_POS_ERROR && offset_limit_cnt == 0; }
void set_unlimited() void set_unlimited()
{ select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; } { select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; }
......
...@@ -3146,7 +3146,8 @@ bool JOIN::make_aggr_tables_info() ...@@ -3146,7 +3146,8 @@ bool JOIN::make_aggr_tables_info()
{ {
/* Check if the storage engine can intercept the query */ /* Check if the storage engine can intercept the query */
Query query= {&all_fields, select_distinct, tables_list, conds, 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); group_by_handler *gbh= ht->create_group_by(thd, &query);
if (gbh) if (gbh)
......
...@@ -103,3 +103,33 @@ count(NULL) ...@@ -103,3 +103,33 @@ count(NULL)
select count(NULL) from seq_1_to_3 limit 0; select count(NULL) from seq_1_to_3 limit 0;
count(NULL) count(NULL)
# End of 10.3 tests # 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; ...@@ -56,3 +56,15 @@ select count(NULL) from seq_1_to_3;
select count(NULL) from seq_1_to_3 limit 0; select count(NULL) from seq_1_to_3 limit 0;
--echo # End of 10.3 tests --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 @@ ...@@ -28,6 +28,7 @@
#include <handler.h> #include <handler.h>
#include <table.h> #include <table.h>
#include <field.h> #include <field.h>
#include <sql_limit.h>
static handlerton *sequence_hton; static handlerton *sequence_hton;
...@@ -361,15 +362,21 @@ static int dummy_savepoint(handlerton *, THD *, void *) { return 0; } ...@@ -361,15 +362,21 @@ static int dummy_savepoint(handlerton *, THD *, void *) { return 0; }
class ha_seq_group_by_handler: public group_by_handler class ha_seq_group_by_handler: public group_by_handler
{ {
Select_limit_counters limit;
List<Item> *fields; List<Item> *fields;
TABLE_LIST *table_list; TABLE_LIST *table_list;
bool first_row; bool first_row;
public: public:
ha_seq_group_by_handler(THD *thd_arg, List<Item> *fields_arg, ha_seq_group_by_handler(THD *thd_arg, List<Item> *fields_arg,
TABLE_LIST *table_list_arg) TABLE_LIST *table_list_arg,
: group_by_handler(thd_arg, sequence_hton), fields(fields_arg), Select_limit_counters *orig_lim)
table_list(table_list_arg) {} : 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() {} ~ha_seq_group_by_handler() {}
int init_scan() { first_row= 1 ; return 0; } int init_scan() { first_row= 1 ; return 0; }
int next_row(); int next_row();
...@@ -425,7 +432,8 @@ create_group_by_handler(THD *thd, Query *query) ...@@ -425,7 +432,8 @@ create_group_by_handler(THD *thd, Query *query)
} }
/* Create handler and return it */ /* 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; return handler;
} }
...@@ -440,7 +448,9 @@ int ha_seq_group_by_handler::next_row() ...@@ -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 Check if this is the first call to the function. If not, we have already
returned all data. 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); DBUG_RETURN(HA_ERR_END_OF_FILE);
first_row= 0; 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