summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2019-10-11 13:08:53 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2019-10-11 13:08:53 +0200
commit7d1d5cc1a64ad8e8a508dc0d4be29a5c0ced499e (patch)
tree9907f857a0259781464de945b4a101e51da420f8
parentce00ea3db0188b22e585f0d64b43358dad0f743c (diff)
downloadmariadb-git-7d1d5cc1a64ad8e8a508dc0d4be29a5c0ced499e.tar.gz
MDEV-16327: Server doesn't account for engines that supports OFFSET on their own.bb-10.5-MDEV-16327-2
Engine get LIMIT/OFFSET info an can it use/reset.
-rw-r--r--sql/group_by_handler.h7
-rw-r--r--sql/sql_limit.h6
-rw-r--r--sql/sql_select.cc3
-rw-r--r--storage/sequence/mysql-test/sequence/group_by.result30
-rw-r--r--storage/sequence/mysql-test/sequence/group_by.test12
-rw-r--r--storage/sequence/sequence.cc20
6 files changed, 71 insertions, 7 deletions
diff --git a/sql/group_by_handler.h b/sql/group_by_handler.h
index 97ee44d73d3..ff3b204fa56 100644
--- a/sql/group_by_handler.h
+++ b/sql/group_by_handler.h
@@ -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
diff --git a/sql/sql_limit.h b/sql/sql_limit.h
index 93a9aae85af..a4fcedac14a 100644
--- a/sql/sql_limit.h
+++ b/sql/sql_limit.h
@@ -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; }
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index e3c4277f960..824d9b4e5bb 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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)
diff --git a/storage/sequence/mysql-test/sequence/group_by.result b/storage/sequence/mysql-test/sequence/group_by.result
index 7902fe6a348..795c32c780f 100644
--- a/storage/sequence/mysql-test/sequence/group_by.result
+++ b/storage/sequence/mysql-test/sequence/group_by.result
@@ -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
diff --git a/storage/sequence/mysql-test/sequence/group_by.test b/storage/sequence/mysql-test/sequence/group_by.test
index 18e44cd2ab1..ca43ba1a5d7 100644
--- a/storage/sequence/mysql-test/sequence/group_by.test
+++ b/storage/sequence/mysql-test/sequence/group_by.test
@@ -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
diff --git a/storage/sequence/sequence.cc b/storage/sequence/sequence.cc
index b9f5d02bd51..8dac7855a6e 100644
--- a/storage/sequence/sequence.cc
+++ b/storage/sequence/sequence.cc
@@ -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;