summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2021-03-28 21:09:51 +0300
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2021-04-21 14:08:58 +0300
commit2d595319bf542dcdeeb058139efa2ef54f645c7b (patch)
tree0b1386cd1340b2a2c175f45f12d64e35e945e1b9
parent3fcc4f6fc24e8bde2f7d3a6aa162d69554bf8e6f (diff)
downloadmariadb-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.cc2
-rw-r--r--sql/sql_limit.h18
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_union.cc2
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))
{