mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-16327: Server doesn't account for engines that supports OFFSET on their own.
Engine get LIMIT/OFFSET info an can it use/reset.
This commit is contained in:
@ -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 @@ public:
|
||||
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;
|
||||
|
||||
|
Reference in New Issue
Block a user