diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2021-03-28 21:09:51 +0300 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2021-04-21 14:08:58 +0300 |
commit | 2d595319bf542dcdeeb058139efa2ef54f645c7b (patch) | |
tree | 0b1386cd1340b2a2c175f45f12d64e35e945e1b9 | |
parent | 3fcc4f6fc24e8bde2f7d3a6aa162d69554bf8e6f (diff) | |
download | mariadb-git-2d595319bf542dcdeeb058139efa2ef54f645c7b.tar.gz |
cleanup: Select_limit_counters rename set_unlimited to clear
The function was originally introduced by eb0804ef5e7eeb059bb193c3c6787e8a4188d34d
MDEV-18553: MDEV-16327 pre-requisits part 1: isolation of LIMIT/OFFSET handling
set_unlimited had an overloaded notion of both clearing the offset value
and the limit value. The code is used for SQL_CALC_ROWS option to
disable the limit clause after the limit is reached, while at the same
time the calling code suppreses sending of rows.
Proposed solution:
Dedicated clear method for query initialization (to ensure no garbage
remains between executions).
Dedicated set_unlimited that only alters the limit value.
-rw-r--r-- | sql/sql_lex.cc | 2 | ||||
-rw-r--r-- | sql/sql_limit.h | 18 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/sql_union.cc | 2 |
4 files changed, 20 insertions, 6 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ca7732316c7..69eaf5e174b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2910,7 +2910,7 @@ void st_select_lex_unit::init_query() { init_query_common(); set_linkage(GLOBAL_OPTIONS_TYPE); - lim.set_unlimited(); + lim.clear(); union_distinct= 0; prepared= optimized= optimized_2= executed= 0; bag_set_op_optimized= 0; diff --git a/sql/sql_limit.h b/sql/sql_limit.h index 6f32e5d17e9..60034201a50 100644 --- a/sql/sql_limit.h +++ b/sql/sql_limit.h @@ -37,8 +37,13 @@ class Select_limit_counters { offset_limit_cnt= offset; select_limit_cnt= limit; - if (select_limit_cnt + offset_limit_cnt >= - select_limit_cnt) + /* + Guard against an overflow condition, where limit + offset exceede + ha_rows value range. This case covers unreasonably large parameter + values that do not have any practical use so assuming in this case + that the query does not have a limit is fine. + */ + if (select_limit_cnt + offset_limit_cnt >= select_limit_cnt) select_limit_cnt+= offset_limit_cnt; else select_limit_cnt= HA_POS_ERROR; @@ -52,7 +57,16 @@ class Select_limit_counters bool is_unlimited() const { return select_limit_cnt == HA_POS_ERROR; } + /* + Set the limit to allow returning an unlimited number of rows. Useful + for cases when we want to continue execution indefinitely after the limit + is reached (for example for SQL_CALC_ROWS extension). + */ void set_unlimited() + { select_limit_cnt= HA_POS_ERROR; } + + /* Reset the limit entirely. */ + void clear() { select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; } bool check_offset(ha_rows sent) const diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7f1045b7680..345bd50918c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7761,8 +7761,8 @@ void mysql_init_multi_delete(LEX *lex) { lex->sql_command= SQLCOM_DELETE_MULTI; mysql_init_select(lex); - lex->first_select_lex()->limit_params.select_limit= 0; - lex->unit.lim.set_unlimited(); + lex->first_select_lex()->limit_params.clear(); + lex->unit.lim.clear(); lex->first_select_lex()->table_list. save_and_clear(&lex->auxiliary_table_list); lex->query_tables= 0; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index f1b00d75de4..2049dfe3ea1 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1340,7 +1340,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, else { sl->join->result= result; - lim.set_unlimited(); + lim.clear(); if (!sl->join->procedure && result->prepare(sl->join->fields_list, this)) { |