mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +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
|
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
|
|||||||
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 @@ public:
|
|||||||
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
|
|||||||
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
|
|||||||
|
|
||||||
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()
|
|||||||
{
|
{
|
||||||
/* 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)
|
|||||||
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;
|
|||||||
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 @@
|
|||||||
#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; }
|
|||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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()
|
|||||||
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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user