diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2019-10-11 13:08:53 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2019-10-11 13:08:53 +0200 |
commit | 7d1d5cc1a64ad8e8a508dc0d4be29a5c0ced499e (patch) | |
tree | 9907f857a0259781464de945b4a101e51da420f8 | |
parent | ce00ea3db0188b22e585f0d64b43358dad0f743c (diff) | |
download | mariadb-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.h | 7 | ||||
-rw-r--r-- | sql/sql_limit.h | 6 | ||||
-rw-r--r-- | sql/sql_select.cc | 3 | ||||
-rw-r--r-- | storage/sequence/mysql-test/sequence/group_by.result | 30 | ||||
-rw-r--r-- | storage/sequence/mysql-test/sequence/group_by.test | 12 | ||||
-rw-r--r-- | storage/sequence/sequence.cc | 20 |
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; |