summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2020-12-19 13:59:37 +0200
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2021-04-21 14:08:58 +0300
commit13cf8f5e9afc7f64df79b41e2b004c28086371f4 (patch)
treeed6bfed9c8488ab688b57bafa42e7eaa68ae2168
parentdd6ad3806856221f1af302e61ebd985905a00060 (diff)
downloadmariadb-git-13cf8f5e9afc7f64df79b41e2b004c28086371f4.tar.gz
cleanup: Refactor select_limit in select lex
Replace * select_lex::offset_limit * select_lex::select_limit * select_lex::explicit_limit with select_lex::Lex_select_limit The Lex_select_limit already existed with the same elements and was used in by the yacc parser. This commit is in preparation for FETCH FIRST implementation, as it simplifies a lot of the code. Additionally, the parser is simplified by making use of the stack to return Lex_select_limit objects. Cleanup of init_query() too. Removes explicit_limit= 0 as it's done a bit later in init_select() with limit_params.empty()
-rw-r--r--sql/group_by_handler.cc2
-rw-r--r--sql/ha_partition.cc14
-rw-r--r--sql/item_subselect.cc26
-rw-r--r--sql/opt_subselect.cc6
-rw-r--r--sql/sql_derived.cc3
-rw-r--r--sql/sql_lex.cc46
-rw-r--r--sql/sql_lex.h9
-rw-r--r--sql/sql_limit.h8
-rw-r--r--sql/sql_parse.cc11
-rw-r--r--sql/sql_select.cc7
-rw-r--r--sql/sql_tvc.cc11
-rw-r--r--sql/sql_union.cc17
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/sql_yacc.yy86
-rw-r--r--sql/structs.h8
-rw-r--r--storage/mroonga/ha_mroonga.cpp12
-rw-r--r--storage/spider/ha_spider.cc2
-rw-r--r--storage/spider/spd_group_by_handler.cc4
-rw-r--r--storage/spider/spd_table.cc16
19 files changed, 129 insertions, 161 deletions
diff --git a/sql/group_by_handler.cc b/sql/group_by_handler.cc
index 71703cf09b6..7b998494af9 100644
--- a/sql/group_by_handler.cc
+++ b/sql/group_by_handler.cc
@@ -58,7 +58,7 @@ int Pushdown_query::execute(JOIN *join)
{
max_limit= join->unit->lim.get_select_limit();
if (join->unit->fake_select_lex)
- reset_item= &join->unit->fake_select_lex->select_limit;
+ reset_item= &join->unit->fake_select_lex->limit_params.select_limit;
}
while (!(err= handler->next_row()))
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 8eddec5511f..91047d05fc8 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -7248,7 +7248,7 @@ bool ha_partition::check_parallel_search()
DBUG_PRINT("info",("partition select_lex: %p", select_lex));
if (!select_lex)
goto not_parallel;
- if (!select_lex->explicit_limit)
+ if (!select_lex->limit_params.explicit_limit)
{
DBUG_PRINT("info",("partition not using explicit_limit"));
goto parallel;
@@ -11544,13 +11544,13 @@ int ha_partition::direct_update_rows_init(List<Item> *update_fields)
table_list= table_list->parent_l;
st_select_lex *select_lex= table_list->select_lex;
DBUG_PRINT("info", ("partition select_lex: %p", select_lex));
- if (select_lex && select_lex->explicit_limit)
+ if (select_lex && select_lex->limit_params.explicit_limit)
{
DBUG_PRINT("info", ("partition explicit_limit=TRUE"));
DBUG_PRINT("info", ("partition offset_limit: %p",
- select_lex->offset_limit));
+ select_lex->limit_params.offset_limit));
DBUG_PRINT("info", ("partition select_limit: %p",
- select_lex->select_limit));
+ select_lex->limit_params.select_limit));
DBUG_PRINT("info", ("partition FALSE by select_lex"));
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
@@ -11736,13 +11736,13 @@ int ha_partition::direct_delete_rows_init()
table_list= table_list->parent_l;
st_select_lex *select_lex= table_list->select_lex;
DBUG_PRINT("info", ("partition select_lex: %p", select_lex));
- if (select_lex && select_lex->explicit_limit)
+ if (select_lex && select_lex->limit_params.explicit_limit)
{
DBUG_PRINT("info", ("partition explicit_limit: TRUE"));
DBUG_PRINT("info", ("partition offset_limit: %p",
- select_lex->offset_limit));
+ select_lex->limit_params.offset_limit));
DBUG_PRINT("info", ("partition select_limit: %p",
- select_lex->select_limit));
+ select_lex->limit_params.select_limit));
DBUG_PRINT("info", ("partition FALSE by select_lex"));
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 3f60203387a..e6c86ea0303 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1715,9 +1715,9 @@ bool Item_exists_subselect::fix_length_and_dec()
DBUG_ENTER("Item_exists_subselect::fix_length_and_dec");
init_length_and_dec();
// If limit is not set or it is constant more than 1
- if (!unit->global_parameters()->select_limit ||
- (unit->global_parameters()->select_limit->basic_const_item() &&
- unit->global_parameters()->select_limit->val_int() > 1))
+ if (!unit->global_parameters()->limit_params.select_limit ||
+ (unit->global_parameters()->limit_params.select_limit->basic_const_item() &&
+ unit->global_parameters()->limit_params.select_limit->val_int() > 1))
{
/*
We need only 1 row to determine existence (i.e. any EXISTS that is not
@@ -1726,9 +1726,9 @@ bool Item_exists_subselect::fix_length_and_dec()
Item *item= new (thd->mem_root) Item_int(thd, (int32) 1);
if (!item)
DBUG_RETURN(TRUE);
- thd->change_item_tree(&unit->global_parameters()->select_limit,
+ thd->change_item_tree(&unit->global_parameters()->limit_params.select_limit,
item);
- unit->global_parameters()->explicit_limit= 1; // we set the limit
+ unit->global_parameters()->limit_params.explicit_limit= 1; // we set the limit
DBUG_PRINT("info", ("Set limit to 1"));
}
DBUG_RETURN(FALSE);
@@ -2907,9 +2907,9 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
select_lex->having->top_level_item();
join_arg->having= select_lex->having;
}
- join_arg->thd->change_item_tree(&unit->global_parameters()->select_limit,
- new (thd->mem_root)
- Item_int(thd, (int32) 1));
+ SELECT_LEX *global_parameters= unit->global_parameters();
+ join_arg->thd->change_item_tree(&global_parameters->limit_params.select_limit,
+ new (thd->mem_root) Item_int(thd, (int32) 1));
unit->lim.set_single_row();
DBUG_RETURN(false);
@@ -3122,10 +3122,10 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg)
(1a) or is a "LIMIT 0" (see MDEV-19429)
(2). there is an OFFSET clause
*/
- if ((first_select->select_limit && // (1)
- (!first_select->select_limit->basic_const_item() || // (1)
- first_select->select_limit->val_uint() == 0)) || // (1a)
- first_select->offset_limit) // (2)
+ if ((first_select->limit_params.select_limit && // (1)
+ (!first_select->limit_params.select_limit->basic_const_item() || // (1)
+ first_select->limit_params.select_limit->val_uint() == 0)) || // (1a)
+ first_select->limit_params.offset_limit) // (2)
{
DBUG_RETURN(FALSE);
}
@@ -3232,7 +3232,7 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg)
/* make EXISTS->IN permanet (see Item_subselect::init()) */
set_exists_transformed();
- first_select->select_limit= NULL;
+ first_select->limit_params.select_limit= NULL;
if (!(in_subs= new (thd->mem_root) Item_in_subselect(thd, left_exp,
first_select)))
{
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 582b1b8e8ef..e09bc179e75 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -615,9 +615,9 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
// (1) - ORDER BY without LIMIT can be removed from IN/EXISTS subqueries
// (2) - for EXISTS, can also remove "ORDER BY ... LIMIT n",
// but cannot remove "ORDER BY ... LIMIT n OFFSET m"
- if (!select_lex->select_limit || // (1)
+ if (!select_lex->limit_params.select_limit || // (1)
(substype == Item_subselect::EXISTS_SUBS && // (2)
- !select_lex->offset_limit)) // (2)
+ !select_lex->limit_params.offset_limit)) // (2)
{
select_lex->join->order= 0;
select_lex->join->skip_sort_order= 1;
@@ -6617,7 +6617,7 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
Item_in_subselect::test_limit). However, once we allow this, here
we should set the correct limit if given in the query.
*/
- in_subs->unit->global_parameters()->select_limit= NULL;
+ in_subs->unit->global_parameters()->limit_params.select_limit= NULL;
in_subs->unit->set_limit(unit->global_parameters());
/*
Set the limit of this JOIN object as well, because normally its being
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index ecd5e7c21fe..60ca2370589 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1448,7 +1448,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
DBUG_RETURN(false);
/* Do not push conditions into unit with global ORDER BY ... LIMIT */
- if (unit->fake_select_lex && unit->fake_select_lex->explicit_limit)
+ if (unit->fake_select_lex &&
+ unit->fake_select_lex->limit_params.explicit_limit)
DBUG_RETURN(false);
/* Check whether any select of 'unit' allows condition pushdown */
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index ea37b0cb100..539152de73d 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2963,7 +2963,7 @@ void st_select_lex::init_query()
n_child_sum_items= 0;
hidden_bit_fields= 0;
fields_in_window_functions= 0;
- subquery_in_having= explicit_limit= 0;
+ subquery_in_having= 0;
is_item_list_lookup= 0;
changed_elements= 0;
first_natural_join_processing= 1;
@@ -3008,8 +3008,7 @@ void st_select_lex::init_select()
ftfunc_list= &ftfunc_list_alloc;
order_list.empty();
/* Set limit and offset to default values */
- select_limit= 0; /* denotes the default limit = HA_POS_ERROR */
- offset_limit= 0; /* denotes the default offset = 0 */
+ limit_params.clear();
is_set_query_expr_tail= false;
select_lock= select_lock_type::NONE;
skip_locked= false;
@@ -3396,7 +3395,7 @@ bool st_select_lex::mark_as_dependent(THD *thd, st_select_lex *last,
*/
bool st_select_lex::test_limit()
{
- if (select_limit != 0)
+ if (limit_params.select_limit)
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"LIMIT & IN/ALL/ANY/SOME subquery");
@@ -3415,24 +3414,26 @@ st_select_lex* st_select_lex_unit::outer_select()
ha_rows st_select_lex::get_offset()
{
- ulonglong val= 0;
+ ha_rows val= 0;
+ Item *offset_limit= limit_params.offset_limit;
if (offset_limit)
{
// see comment for st_select_lex::get_limit()
bool err= offset_limit->fix_fields_if_needed(master_unit()->thd, NULL);
DBUG_ASSERT(!err);
- val= err ? HA_POS_ERROR : offset_limit->val_uint();
+ val= err ? HA_POS_ERROR : (ha_rows)offset_limit->val_uint();
}
- return (ha_rows)val;
+ return val;
}
ha_rows st_select_lex::get_limit()
{
- ulonglong val= HA_POS_ERROR;
+ ha_rows val= HA_POS_ERROR;
+ Item *select_limit= limit_params.select_limit;
if (select_limit)
{
/*
@@ -3463,10 +3464,10 @@ ha_rows st_select_lex::get_limit()
*/
bool err= select_limit->fix_fields_if_needed(master_unit()->thd, NULL);
DBUG_ASSERT(!err);
- val= err ? HA_POS_ERROR : select_limit->val_uint();
+ val= err ? HA_POS_ERROR : (ha_rows) select_limit->val_uint();
}
- return (ha_rows)val;
+ return val;
}
@@ -3639,10 +3640,10 @@ void LEX::print(String *str, enum_query_type query_type)
(*ord->item)->print(str, query_type);
}
}
- if (sel->select_limit)
+ if (sel->limit_params.select_limit)
{
str->append(STRING_WITH_LEN(" LIMIT "));
- sel->select_limit->print(str, query_type);
+ sel->limit_params.select_limit->print(str, query_type);
}
}
else if (sql_command == SQLCOM_DELETE)
@@ -3674,10 +3675,10 @@ void LEX::print(String *str, enum_query_type query_type)
(*ord->item)->print(str, query_type);
}
}
- if (sel->select_limit)
+ if (sel->limit_params.select_limit)
{
str->append(STRING_WITH_LEN(" LIMIT "));
- sel->select_limit->print(str, query_type);
+ sel->limit_params.select_limit->print(str, query_type);
}
}
else
@@ -3779,15 +3780,16 @@ void st_select_lex::print_limit(THD *thd,
return;
}
}
- if (explicit_limit && select_limit)
+ if (limit_params.explicit_limit &&
+ limit_params.select_limit)
{
str->append(STRING_WITH_LEN(" limit "));
- if (offset_limit)
+ if (limit_params.offset_limit)
{
- offset_limit->print(str, query_type);
+ limit_params.offset_limit->print(str, query_type);
str->append(',');
}
- select_limit->print(str, query_type);
+ limit_params.select_limit->print(str, query_type);
}
}
@@ -4001,7 +4003,7 @@ bool LEX::can_be_merged()
first_select_lex()->with_sum_func == 0 &&
first_select_lex()->table_list.elements >= 1 &&
!(first_select_lex()->options & SELECT_DISTINCT) &&
- first_select_lex()->select_limit == 0);
+ first_select_lex()->limit_params.select_limit == 0);
}
@@ -9758,9 +9760,7 @@ bool Lex_order_limit_lock::set_to(SELECT_LEX *sel)
return TRUE;
}
lock.set_to(sel);
- sel->explicit_limit= limit.explicit_limit;
- sel->select_limit= limit.select_limit;
- sel->offset_limit= limit.offset_limit;
+ sel->limit_params= limit;
if (order_list)
{
if (sel->get_linkage() != GLOBAL_OPTIONS_TYPE &&
@@ -10079,7 +10079,7 @@ LEX::add_tail_to_query_expression_body_ext_parens(SELECT_LEX_UNIT *unit,
pop_select();
if (sel->is_set_query_expr_tail)
{
- if (!l->order_list && !sel->explicit_limit)
+ if (!l->order_list && !sel->limit_params.explicit_limit)
l->order_list= &sel->order_list;
else
{
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 84f5d1dc73f..b9bc108c419 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1191,7 +1191,8 @@ public:
SQL_I_List<ORDER> order_list; /* ORDER clause */
SQL_I_List<ORDER> gorder_list;
- Item *select_limit, *offset_limit; /* LIMIT clause parameters */
+ Lex_select_limit limit_params; /* LIMIT clause parameters */
+
bool is_set_query_expr_tail;
/// Array of pointers to top elements of all_fields list
@@ -1260,8 +1261,6 @@ public:
/* Number of Item_sum-derived objects in children and descendant SELECTs */
uint n_child_sum_items;
- /* explicit LIMIT clause was used */
- bool explicit_limit;
/*
This array is used to note whether we have any candidates for
expression caching in the corresponding clauses
@@ -1512,7 +1511,7 @@ public:
return (next_select() == 0 && group_list.elements == 0 &&
having == 0 && with_sum_func == 0 &&
table_list.elements >= 1 && !(options & SELECT_DISTINCT) &&
- select_limit == 0);
+ limit_params.select_limit == 0);
}
void mark_as_belong_to_derived(TABLE_LIST *derived);
void increase_derived_records(ha_rows records);
@@ -1574,7 +1573,7 @@ public:
ORDER *find_common_window_func_partition_fields(THD *thd);
bool cond_pushdown_is_allowed() const
- { return !olap && !explicit_limit && !tvc; }
+ { return !olap && !limit_params.explicit_limit && !tvc; }
bool build_pushable_cond_for_having_pushdown(THD *thd, Item *cond);
void pushdown_cond_into_where_clause(THD *thd, Item *extracted_cond,
diff --git a/sql/sql_limit.h b/sql/sql_limit.h
index a4fcedac14a..943d96940bb 100644
--- a/sql/sql_limit.h
+++ b/sql/sql_limit.h
@@ -50,22 +50,22 @@ class Select_limit_counters
select_limit_cnt= 1;
}
- bool is_unlimited()
+ bool is_unlimited() const
{ 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; }
- bool check_offset(ha_rows sent)
+ bool check_offset(ha_rows sent) const
{
return sent < offset_limit_cnt;
}
void remove_offset() { offset_limit_cnt= 0; }
- ha_rows get_select_limit()
+ ha_rows get_select_limit() const
{ return select_limit_cnt; }
- ha_rows get_offset_limit()
+ ha_rows get_offset_limit() const
{ return offset_limit_cnt; }
};
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 29884cd843e..7f1045b7680 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4396,7 +4396,7 @@ mysql_execute_command(THD *thd)
if (lex->ignore)
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_UPDATE_IGNORE);
- DBUG_ASSERT(select_lex->offset_limit == 0);
+ DBUG_ASSERT(select_lex->limit_params.offset_limit == 0);
unit->set_limit(select_lex);
MYSQL_UPDATE_START(thd->query());
res= up_result= mysql_update(thd, all_tables,
@@ -4772,7 +4772,7 @@ mysql_execute_command(THD *thd)
if ((res= delete_precheck(thd, all_tables)))
break;
- DBUG_ASSERT(select_lex->offset_limit == 0);
+ DBUG_ASSERT(select_lex->limit_params.offset_limit == 0);
unit->set_limit(select_lex);
MYSQL_DELETE_START(thd->query());
@@ -6156,8 +6156,8 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
/* assign global limit variable if limit is not given */
{
SELECT_LEX *param= lex->unit.global_parameters();
- if (!param->explicit_limit)
- param->select_limit=
+ if (!param->limit_params.explicit_limit)
+ param->limit_params.select_limit=
new (thd->mem_root) Item_int(thd,
(ulonglong) thd->variables.select_limit);
}
@@ -7761,7 +7761,7 @@ void mysql_init_multi_delete(LEX *lex)
{
lex->sql_command= SQLCOM_DELETE_MULTI;
mysql_init_select(lex);
- lex->first_select_lex()->select_limit= 0;
+ lex->first_select_lex()->limit_params.select_limit= 0;
lex->unit.lim.set_unlimited();
lex->first_select_lex()->table_list.
save_and_clear(&lex->auxiliary_table_list);
@@ -8964,7 +8964,6 @@ bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
fake_select_lex->make_empty_select();
fake_select_lex->set_linkage(GLOBAL_OPTIONS_TYPE);
- fake_select_lex->select_limit= 0;
fake_select_lex->no_table_names_allowed= 1;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 849e0943acd..34c5b0cbddb 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -257,9 +257,10 @@ static ORDER *create_distinct_group(THD *thd, Ref_ptr_array ref_pointer_array,
static bool test_if_subpart(ORDER *a,ORDER *b);
static TABLE *get_sort_by_table(ORDER *a,ORDER *b,List<TABLE_LIST> &tables,
table_map const_tables);
-static void calc_group_buffer(JOIN *join,ORDER *group);
+static void calc_group_buffer(JOIN *join, ORDER *group);
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
-static bool alloc_group_fields(JOIN *join,ORDER *group);
+static bool alloc_group_fields(JOIN *join, ORDER *group);
+static bool alloc_order_fields(JOIN *join, ORDER *group);
// Create list for using with tempory table
static bool change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &new_list1,
@@ -22034,7 +22035,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
join->do_send_rows= 0;
if (join->unit->fake_select_lex)
- join->unit->fake_select_lex->select_limit= 0;
+ join->unit->fake_select_lex->limit_params.select_limit= 0;
DBUG_RETURN(NESTED_LOOP_OK);
}
}
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc
index 576927ea086..cfd46336d07 100644
--- a/sql/sql_tvc.cc
+++ b/sql/sql_tvc.cc
@@ -651,7 +651,8 @@ static bool create_tvc_name(THD *thd, st_select_lex *parent_select,
bool table_value_constr::to_be_wrapped_as_with_tail()
{
return select_lex->master_unit()->first_select()->next_select() &&
- select_lex->order_list.elements && select_lex->explicit_limit;
+ select_lex->order_list.elements &&
+ select_lex->limit_params.explicit_limit;
}
@@ -799,15 +800,11 @@ st_select_lex *wrap_tvc_with_tail(THD *thd, st_select_lex *tvc_sl)
return NULL;
wrapper_sl->order_list= tvc_sl->order_list;
- wrapper_sl->select_limit= tvc_sl->select_limit;
- wrapper_sl->offset_limit= tvc_sl->offset_limit;
+ wrapper_sl->limit_params= tvc_sl->limit_params;
wrapper_sl->braces= tvc_sl->braces;
- wrapper_sl->explicit_limit= tvc_sl->explicit_limit;
tvc_sl->order_list.empty();
- tvc_sl->select_limit= NULL;
- tvc_sl->offset_limit= NULL;
+ tvc_sl->limit_params.clear();
tvc_sl->braces= 0;
- tvc_sl->explicit_limit= false;
if (tvc_sl->select_number == 1)
{
tvc_sl->select_number= wrapper_sl->select_number;
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index b88d78c0db3..f1b00d75de4 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1083,7 +1083,8 @@ bool st_select_lex_unit::prepare_join(THD *thd_arg, SELECT_LEX *sl,
thd_arg->lex->current_select= sl;
- can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
+ can_skip_order_by= is_union_select && !(sl->braces &&
+ sl->limit_params.explicit_limit);
saved_error= join->prepare(sl->table_list.first,
(derived && derived->merged ? NULL : sl->where),
@@ -1449,7 +1450,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
if (fake_select_lex)
{
if (fake_select_lex->order_list.first ||
- fake_select_lex->explicit_limit)
+ fake_select_lex->limit_params.explicit_limit)
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"global ORDER_BY/LIMIT in recursive CTE spec");
@@ -1509,7 +1510,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
if (!unit->first_select()->next_select())
{
if (!unit->fake_select_lex)
- {
+ {
Query_arena *arena, backup_arena;
arena= thd->activate_stmt_arena_if_needed(&backup_arena);
bool rc= unit->add_fake_select_lex(thd);
@@ -1520,17 +1521,13 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
}
SELECT_LEX *fake= unit->fake_select_lex;
fake->order_list= sl->order_list;
- fake->explicit_limit= sl->explicit_limit;
- fake->select_limit= sl->select_limit;
- fake->offset_limit= sl->offset_limit;
+ fake->limit_params= sl->limit_params;
sl->order_list.empty();
- sl->explicit_limit= 0;
- sl->select_limit= 0;
- sl->offset_limit= 0;
+ sl->limit_params.clear();
if (describe)
fake->options|= SELECT_DESCRIBE;
}
- else if (!sl->explicit_limit)
+ else if (!sl->limit_params.explicit_limit)
sl->order_list.empty();
}
}
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index a5b2fb749d6..c8f865fe475 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1936,7 +1936,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
*/
if ((!view->view && !view->belong_to_view) ||
thd->lex->sql_command == SQLCOM_INSERT ||
- thd->lex->first_select_lex()->select_limit == 0)
+ thd->lex->first_select_lex()->limit_params.select_limit == 0)
DBUG_RETURN(FALSE); /* it is normal table or query without LIMIT */
table= view->table;
view= view->top_table();
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 4d677c519f2..a330ed328a4 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -10943,13 +10943,11 @@ sum_expr:
Item_func_group_concat(thd, Lex->current_context(),
$3, $5,
sel->gorder_list, $7, $8,
- sel->select_limit,
- sel->offset_limit);
+ sel->limit_params.select_limit,
+ sel->limit_params.offset_limit);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
- sel->select_limit= NULL;
- sel->offset_limit= NULL;
- sel->explicit_limit= 0;
+ sel->limit_params.clear();
$5->empty();
sel->gorder_list.empty();
}
@@ -10975,13 +10973,11 @@ sum_expr:
Item_func_json_arrayagg(thd, Lex->current_context(),
$3, args,
sel->gorder_list, s, $7,
- sel->select_limit,
- sel->offset_limit);
+ sel->limit_params.select_limit,
+ sel->limit_params.offset_limit);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
- sel->select_limit= NULL;
- sel->offset_limit= NULL;
- sel->explicit_limit= 0;
+ sel->limit_params.clear();
$5->empty();
sel->gorder_list.empty();
}
@@ -11308,38 +11304,18 @@ opt_glimit_clause:
| glimit_clause { $$ = 1; }
;
-glimit_clause_init:
- LIMIT{}
- ;
glimit_clause:
- glimit_clause_init glimit_options
+ LIMIT glimit_options
{
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
}
;
glimit_options:
- limit_option
+ limit_options
{
- SELECT_LEX *sel= Select;
- sel->select_limit= $1;
- sel->offset_limit= 0;
- sel->explicit_limit= 1;
- }
- | limit_option ',' limit_option
- {
- SELECT_LEX *sel= Select;
- sel->select_limit= $3;
- sel->offset_limit= $1;
- sel->explicit_limit= 1;
- }
- | limit_option OFFSET_SYM limit_option
- {
- SELECT_LEX *sel= Select;
- sel->select_limit= $1;
- sel->offset_limit= $3;
- sel->explicit_limit= 1;
+ Select->limit_params= $1;
}
;
@@ -12478,14 +12454,15 @@ order_list:
;
order_dir:
- /* empty */ { $$ = 1; }
- | ASC { $$ =1; }
- | DESC { $$ =0; }
+ /* empty */ { $$= 1; }
+ | ASC { $$= 1; }
+ | DESC { $$= 0; }
;
+
opt_limit_clause:
/* empty */
- { $$.empty(); }
+ { $$.clear(); }
| limit_clause
{ $$= $1; }
;
@@ -12506,9 +12483,7 @@ limit_clause:
}
| LIMIT ROWS_SYM EXAMINED_SYM limit_rows_option
{
- $$.select_limit= 0;
- $$.offset_limit= 0;
- $$.explicit_limit= 0;
+ $$.clear();
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
}
;
@@ -12516,9 +12491,7 @@ limit_clause:
opt_global_limit_clause:
opt_limit_clause
{
- Select->explicit_limit= $1.explicit_limit;
- Select->select_limit= $1.select_limit;
- Select->offset_limit= $1.offset_limit;
+ Select->limit_params= $1;
}
;
@@ -12581,8 +12554,7 @@ limit_option:
limit_rows_option:
limit_option
{
- LEX *lex=Lex;
- lex->limit_rows_examined= $1;
+ Lex->limit_rows_examined= $1;
}
;
@@ -12590,14 +12562,14 @@ delete_limit_clause:
/* empty */
{
LEX *lex=Lex;
- lex->current_select->select_limit= 0;
+ lex->current_select->limit_params.select_limit= 0;
}
| LIMIT limit_option
{
SELECT_LEX *sel= Select;
- sel->select_limit= $2;
+ sel->limit_params.select_limit= $2;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
- sel->explicit_limit= 1;
+ sel->limit_params.explicit_limit= 1;
}
| LIMIT ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; }
| LIMIT limit_option ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; }
@@ -12620,7 +12592,7 @@ order_limit_lock:
if (!$$)
YYABORT;
$$->order_list= NULL;
- $$->limit.empty();
+ $$->limit.clear();
$$->lock= $1;
}
;
@@ -12674,11 +12646,9 @@ order_or_limit:
}
| limit_clause
{
- Lex_order_limit_lock *op= $$= new(thd->mem_root) Lex_order_limit_lock;
+ $$= new(thd->mem_root) Lex_order_limit_lock;
if (!$$)
YYABORT;
- op->order_list= NULL;
- op->limit= $1;
$$->order_list= NULL;
$$->limit= $1;
}
@@ -17028,6 +16998,7 @@ handler_tail:
| table_ident_nodb READ_SYM
{
LEX *lex=Lex;
+ SELECT_LEX *select= Select;
if (unlikely(lex->sphead))
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER"));
lex->clause_that_disallows_subselect= "HANDLER..READ";
@@ -17036,8 +17007,8 @@ handler_tail:
Item *one= new (thd->mem_root) Item_int(thd, (int32) 1);
if (unlikely(one == NULL))
MYSQL_YYABORT;
- lex->current_select->select_limit= one;
- lex->current_select->offset_limit= 0;
+ select->limit_params.select_limit= one;
+ select->limit_params.offset_limit= 0;
lex->limit_rows_examined= 0;
if (!lex->current_select->add_table_to_list(thd, $1, 0, 0))
MYSQL_YYABORT;
@@ -17045,14 +17016,15 @@ handler_tail:
handler_read_or_scan opt_where_clause opt_global_limit_clause
{
LEX *lex=Lex;
+ SELECT_LEX *select= Select;
lex->clause_that_disallows_subselect= NULL;
- if (!lex->current_select->explicit_limit)
+ if (!lex->current_select->limit_params.explicit_limit)
{
Item *one= new (thd->mem_root) Item_int(thd, (int32) 1);
if (one == NULL)
MYSQL_YYABORT;
- lex->current_select->select_limit= one;
- lex->current_select->offset_limit= 0;
+ select->limit_params.select_limit= one;
+ select->limit_params.offset_limit= 0;
lex->limit_rows_examined= 0;
}
/* Stored functions are not supported for HANDLER READ. */
diff --git a/sql/structs.h b/sql/structs.h
index df362f76f82..adb1fec119b 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -824,13 +824,15 @@ public:
class Lex_select_limit
{
public:
+ /* explicit LIMIT clause was used */
bool explicit_limit;
Item *select_limit, *offset_limit;
- void empty()
+ void clear()
{
- explicit_limit= FALSE;
- select_limit= offset_limit= NULL;
+ explicit_limit= FALSE; // No explicit limit given by user
+ select_limit= NULL; // denotes the default limit = HA_POS_ERROR
+ offset_limit= NULL; // denotes the default offset = 0
}
};
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index 0282897f4f3..1cddd8fc4a8 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -10181,16 +10181,16 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
!MRN_SELECT_LEX_GET_HAVING_COND(select_lex) &&
select_lex->table_list.elements == 1 &&
select_lex->order_list.elements &&
- select_lex->explicit_limit &&
- select_lex->select_limit &&
- select_lex->select_limit->val_int() > 0
+ select_lex->limit_params.explicit_limit &&
+ select_lex->limit_params.select_limit &&
+ select_lex->limit_params.select_limit->val_int() > 0
) {
- if (select_lex->offset_limit) {
- *limit = select_lex->offset_limit->val_int();
+ if (select_lex->limit_params.offset_limit) {
+ *limit = select_lex->limit_params.offset_limit->val_int();
} else {
*limit = 0;
}
- *limit += select_lex->select_limit->val_int();
+ *limit += select_lex->limit_params.select_limit->val_int();
if (*limit > (longlong)INT_MAX) {
DBUG_PRINT("info",
("mroonga: fast_order_limit = false: "
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc
index 6cee49cd6da..fe66b6e889f 100644
--- a/storage/spider/ha_spider.cc
+++ b/storage/spider/ha_spider.cc
@@ -13937,7 +13937,7 @@ void ha_spider::check_pre_call(
select_lex, &select_limit, &offset_limit);
if (
select_lex &&
- (!select_lex->explicit_limit || !select_limit)
+ (!select_lex->limit_params.explicit_limit || !select_limit)
) {
use_pre_call = TRUE;
}
diff --git a/storage/spider/spd_group_by_handler.cc b/storage/spider/spd_group_by_handler.cc
index 30d81b5a4ae..7f26f91cc70 100644
--- a/storage/spider/spd_group_by_handler.cc
+++ b/storage/spider/spd_group_by_handler.cc
@@ -1256,7 +1256,7 @@ int spider_group_by_handler::init_scan()
share->direct_order_limit);
if (
direct_order_limit &&
- select_lex->explicit_limit &&
+ select_lex->limit_params.explicit_limit &&
!(select_lex->options & OPTION_FOUND_ROWS) &&
select_limit < direct_order_limit /* - offset_limit */
) {
@@ -1291,7 +1291,7 @@ int spider_group_by_handler::init_scan()
result_list->internal_limit >= result_list->split_read ?
result_list->split_read : result_list->internal_limit;
- if (select_lex->explicit_limit)
+ if (select_lex->limit_params.explicit_limit)
{
result_list->internal_offset += offset_limit;
} else {
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index 10f468b74e0..5405637da39 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -8961,12 +8961,12 @@ void spider_get_select_limit_from_select_lex(
DBUG_ENTER("spider_get_select_limit_from_select_lex");
*select_limit = 9223372036854775807LL;
*offset_limit = 0;
- if (select_lex && select_lex->explicit_limit)
+ if (select_lex && select_lex->limit_params.explicit_limit)
{
- *select_limit = select_lex->select_limit ?
- select_lex->select_limit->val_int() : 0;
- *offset_limit = select_lex->offset_limit ?
- select_lex->offset_limit->val_int() : 0;
+ *select_limit = select_lex->limit_params.select_limit ?
+ select_lex->limit_params.select_limit->val_int() : 0;
+ *offset_limit = select_lex->limit_params.offset_limit ?
+ select_lex->limit_params.offset_limit->val_int() : 0;
}
DBUG_VOID_RETURN;
}
@@ -9158,13 +9158,13 @@ longlong spider_split_read_param(
result_list->set_split_read = TRUE;
}
DBUG_PRINT("info",("spider result_list->semi_split_read=%f", result_list->semi_split_read));
- DBUG_PRINT("info",("spider select_lex->explicit_limit=%d", select_lex ? select_lex->explicit_limit : 0));
+ DBUG_PRINT("info",("spider select_lex->explicit_limit=%d", select_lex ? select_lex->limit_params.explicit_limit : 0));
DBUG_PRINT("info",("spider OPTION_FOUND_ROWS=%s", select_lex && (select_lex->options & OPTION_FOUND_ROWS) ? "TRUE" : "FALSE"));
DBUG_PRINT("info",("spider select_lex->group_list.elements=%u", select_lex ? select_lex->group_list.elements : 0));
DBUG_PRINT("info",("spider select_lex->with_sum_func=%s", select_lex && select_lex->with_sum_func ? "TRUE" : "FALSE"));
if (
result_list->semi_split_read > 0 &&
- select_lex && select_lex->explicit_limit &&
+ select_lex && select_lex->limit_params.explicit_limit &&
!(select_lex->options & OPTION_FOUND_ROWS) &&
!select_lex->group_list.elements &&
!select_lex->with_sum_func
@@ -9394,7 +9394,7 @@ bool spider_check_direct_order_limit(
select_lex ? select_lex->order_list.elements : 0));
if (
!first_check ||
- !select_lex->explicit_limit ||
+ !select_lex->limit_params.explicit_limit ||
(select_lex->options & OPTION_FOUND_ROWS) ||
(
#ifdef HANDLER_HAS_DIRECT_AGGREGATE