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()
This commit is contained in:
Vicențiu Ciorbaru 2020-12-19 13:59:37 +02:00
parent dd6ad38068
commit 13cf8f5e9a
19 changed files with 129 additions and 161 deletions

View File

@ -58,7 +58,7 @@ int Pushdown_query::execute(JOIN *join)
{ {
max_limit= join->unit->lim.get_select_limit(); max_limit= join->unit->lim.get_select_limit();
if (join->unit->fake_select_lex) 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())) while (!(err= handler->next_row()))

View File

@ -7248,7 +7248,7 @@ bool ha_partition::check_parallel_search()
DBUG_PRINT("info",("partition select_lex: %p", select_lex)); DBUG_PRINT("info",("partition select_lex: %p", select_lex));
if (!select_lex) if (!select_lex)
goto not_parallel; goto not_parallel;
if (!select_lex->explicit_limit) if (!select_lex->limit_params.explicit_limit)
{ {
DBUG_PRINT("info",("partition not using explicit_limit")); DBUG_PRINT("info",("partition not using explicit_limit"));
goto parallel; goto parallel;
@ -11544,13 +11544,13 @@ int ha_partition::direct_update_rows_init(List<Item> *update_fields)
table_list= table_list->parent_l; table_list= table_list->parent_l;
st_select_lex *select_lex= table_list->select_lex; st_select_lex *select_lex= table_list->select_lex;
DBUG_PRINT("info", ("partition select_lex: %p", 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 explicit_limit=TRUE"));
DBUG_PRINT("info", ("partition offset_limit: %p", DBUG_PRINT("info", ("partition offset_limit: %p",
select_lex->offset_limit)); select_lex->limit_params.offset_limit));
DBUG_PRINT("info", ("partition select_limit: %p", 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_PRINT("info", ("partition FALSE by select_lex"));
DBUG_RETURN(HA_ERR_WRONG_COMMAND); DBUG_RETURN(HA_ERR_WRONG_COMMAND);
} }
@ -11736,13 +11736,13 @@ int ha_partition::direct_delete_rows_init()
table_list= table_list->parent_l; table_list= table_list->parent_l;
st_select_lex *select_lex= table_list->select_lex; st_select_lex *select_lex= table_list->select_lex;
DBUG_PRINT("info", ("partition select_lex: %p", 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 explicit_limit: TRUE"));
DBUG_PRINT("info", ("partition offset_limit: %p", DBUG_PRINT("info", ("partition offset_limit: %p",
select_lex->offset_limit)); select_lex->limit_params.offset_limit));
DBUG_PRINT("info", ("partition select_limit: %p", 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_PRINT("info", ("partition FALSE by select_lex"));
DBUG_RETURN(HA_ERR_WRONG_COMMAND); DBUG_RETURN(HA_ERR_WRONG_COMMAND);
} }

View File

@ -1715,9 +1715,9 @@ bool Item_exists_subselect::fix_length_and_dec()
DBUG_ENTER("Item_exists_subselect::fix_length_and_dec"); DBUG_ENTER("Item_exists_subselect::fix_length_and_dec");
init_length_and_dec(); init_length_and_dec();
// If limit is not set or it is constant more than 1 // If limit is not set or it is constant more than 1
if (!unit->global_parameters()->select_limit || if (!unit->global_parameters()->limit_params.select_limit ||
(unit->global_parameters()->select_limit->basic_const_item() && (unit->global_parameters()->limit_params.select_limit->basic_const_item() &&
unit->global_parameters()->select_limit->val_int() > 1)) 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 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); Item *item= new (thd->mem_root) Item_int(thd, (int32) 1);
if (!item) if (!item)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
thd->change_item_tree(&unit->global_parameters()->select_limit, thd->change_item_tree(&unit->global_parameters()->limit_params.select_limit,
item); 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_PRINT("info", ("Set limit to 1"));
} }
DBUG_RETURN(FALSE); 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(); select_lex->having->top_level_item();
join_arg->having= select_lex->having; join_arg->having= select_lex->having;
} }
join_arg->thd->change_item_tree(&unit->global_parameters()->select_limit, SELECT_LEX *global_parameters= unit->global_parameters();
new (thd->mem_root) join_arg->thd->change_item_tree(&global_parameters->limit_params.select_limit,
Item_int(thd, (int32) 1)); new (thd->mem_root) Item_int(thd, (int32) 1));
unit->lim.set_single_row(); unit->lim.set_single_row();
DBUG_RETURN(false); 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) (1a) or is a "LIMIT 0" (see MDEV-19429)
(2). there is an OFFSET clause (2). there is an OFFSET clause
*/ */
if ((first_select->select_limit && // (1) if ((first_select->limit_params.select_limit && // (1)
(!first_select->select_limit->basic_const_item() || // (1) (!first_select->limit_params.select_limit->basic_const_item() || // (1)
first_select->select_limit->val_uint() == 0)) || // (1a) first_select->limit_params.select_limit->val_uint() == 0)) || // (1a)
first_select->offset_limit) // (2) first_select->limit_params.offset_limit) // (2)
{ {
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
@ -3232,7 +3232,7 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg)
/* make EXISTS->IN permanet (see Item_subselect::init()) */ /* make EXISTS->IN permanet (see Item_subselect::init()) */
set_exists_transformed(); 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, if (!(in_subs= new (thd->mem_root) Item_in_subselect(thd, left_exp,
first_select))) first_select)))
{ {

View File

@ -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 // (1) - ORDER BY without LIMIT can be removed from IN/EXISTS subqueries
// (2) - for EXISTS, can also remove "ORDER BY ... LIMIT n", // (2) - for EXISTS, can also remove "ORDER BY ... LIMIT n",
// but cannot remove "ORDER BY ... LIMIT n OFFSET m" // 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) (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->order= 0;
select_lex->join->skip_sort_order= 1; 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 Item_in_subselect::test_limit). However, once we allow this, here
we should set the correct limit if given in the query. 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()); in_subs->unit->set_limit(unit->global_parameters());
/* /*
Set the limit of this JOIN object as well, because normally its being Set the limit of this JOIN object as well, because normally its being

View File

@ -1448,7 +1448,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
DBUG_RETURN(false); DBUG_RETURN(false);
/* Do not push conditions into unit with global ORDER BY ... LIMIT */ /* 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); DBUG_RETURN(false);
/* Check whether any select of 'unit' allows condition pushdown */ /* Check whether any select of 'unit' allows condition pushdown */

View File

@ -2963,7 +2963,7 @@ void st_select_lex::init_query()
n_child_sum_items= 0; n_child_sum_items= 0;
hidden_bit_fields= 0; hidden_bit_fields= 0;
fields_in_window_functions= 0; fields_in_window_functions= 0;
subquery_in_having= explicit_limit= 0; subquery_in_having= 0;
is_item_list_lookup= 0; is_item_list_lookup= 0;
changed_elements= 0; changed_elements= 0;
first_natural_join_processing= 1; first_natural_join_processing= 1;
@ -3008,8 +3008,7 @@ void st_select_lex::init_select()
ftfunc_list= &ftfunc_list_alloc; ftfunc_list= &ftfunc_list_alloc;
order_list.empty(); order_list.empty();
/* Set limit and offset to default values */ /* Set limit and offset to default values */
select_limit= 0; /* denotes the default limit = HA_POS_ERROR */ limit_params.clear();
offset_limit= 0; /* denotes the default offset = 0 */
is_set_query_expr_tail= false; is_set_query_expr_tail= false;
select_lock= select_lock_type::NONE; select_lock= select_lock_type::NONE;
skip_locked= false; 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() bool st_select_lex::test_limit()
{ {
if (select_limit != 0) if (limit_params.select_limit)
{ {
my_error(ER_NOT_SUPPORTED_YET, MYF(0), my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"LIMIT & IN/ALL/ANY/SOME subquery"); "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() ha_rows st_select_lex::get_offset()
{ {
ulonglong val= 0; ha_rows val= 0;
Item *offset_limit= limit_params.offset_limit;
if (offset_limit) if (offset_limit)
{ {
// see comment for st_select_lex::get_limit() // see comment for st_select_lex::get_limit()
bool err= offset_limit->fix_fields_if_needed(master_unit()->thd, NULL); bool err= offset_limit->fix_fields_if_needed(master_unit()->thd, NULL);
DBUG_ASSERT(!err); 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() 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) 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); bool err= select_limit->fix_fields_if_needed(master_unit()->thd, NULL);
DBUG_ASSERT(!err); 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); (*ord->item)->print(str, query_type);
} }
} }
if (sel->select_limit) if (sel->limit_params.select_limit)
{ {
str->append(STRING_WITH_LEN(" 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) 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); (*ord->item)->print(str, query_type);
} }
} }
if (sel->select_limit) if (sel->limit_params.select_limit)
{ {
str->append(STRING_WITH_LEN(" LIMIT ")); str->append(STRING_WITH_LEN(" LIMIT "));
sel->select_limit->print(str, query_type); sel->limit_params.select_limit->print(str, query_type);
} }
} }
else else
@ -3779,15 +3780,16 @@ void st_select_lex::print_limit(THD *thd,
return; return;
} }
} }
if (explicit_limit && select_limit) if (limit_params.explicit_limit &&
limit_params.select_limit)
{ {
str->append(STRING_WITH_LEN(" 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(','); 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()->with_sum_func == 0 &&
first_select_lex()->table_list.elements >= 1 && first_select_lex()->table_list.elements >= 1 &&
!(first_select_lex()->options & SELECT_DISTINCT) && !(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; return TRUE;
} }
lock.set_to(sel); lock.set_to(sel);
sel->explicit_limit= limit.explicit_limit; sel->limit_params= limit;
sel->select_limit= limit.select_limit;
sel->offset_limit= limit.offset_limit;
if (order_list) if (order_list)
{ {
if (sel->get_linkage() != GLOBAL_OPTIONS_TYPE && 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(); pop_select();
if (sel->is_set_query_expr_tail) 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; l->order_list= &sel->order_list;
else else
{ {

View File

@ -1191,7 +1191,8 @@ public:
SQL_I_List<ORDER> order_list; /* ORDER clause */ SQL_I_List<ORDER> order_list; /* ORDER clause */
SQL_I_List<ORDER> gorder_list; 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; bool is_set_query_expr_tail;
/// Array of pointers to top elements of all_fields list /// 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 */ /* Number of Item_sum-derived objects in children and descendant SELECTs */
uint n_child_sum_items; 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 This array is used to note whether we have any candidates for
expression caching in the corresponding clauses expression caching in the corresponding clauses
@ -1512,7 +1511,7 @@ public:
return (next_select() == 0 && group_list.elements == 0 && return (next_select() == 0 && group_list.elements == 0 &&
having == 0 && with_sum_func == 0 && having == 0 && with_sum_func == 0 &&
table_list.elements >= 1 && !(options & SELECT_DISTINCT) && 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 mark_as_belong_to_derived(TABLE_LIST *derived);
void increase_derived_records(ha_rows records); void increase_derived_records(ha_rows records);
@ -1574,7 +1573,7 @@ public:
ORDER *find_common_window_func_partition_fields(THD *thd); ORDER *find_common_window_func_partition_fields(THD *thd);
bool cond_pushdown_is_allowed() const 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); bool build_pushable_cond_for_having_pushdown(THD *thd, Item *cond);
void pushdown_cond_into_where_clause(THD *thd, Item *extracted_cond, void pushdown_cond_into_where_clause(THD *thd, Item *extracted_cond,

View File

@ -50,22 +50,22 @@ class Select_limit_counters
select_limit_cnt= 1; select_limit_cnt= 1;
} }
bool is_unlimited() bool is_unlimited() const
{ return select_limit_cnt == HA_POS_ERROR; } { return select_limit_cnt == HA_POS_ERROR; }
bool is_unrestricted() bool is_unrestricted()
{ return select_limit_cnt == HA_POS_ERROR && offset_limit_cnt == 0; } { return select_limit_cnt == HA_POS_ERROR && offset_limit_cnt == 0; }
void set_unlimited() void set_unlimited()
{ select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; } { 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; return sent < offset_limit_cnt;
} }
void remove_offset() { offset_limit_cnt= 0; } void remove_offset() { offset_limit_cnt= 0; }
ha_rows get_select_limit() ha_rows get_select_limit() const
{ return select_limit_cnt; } { return select_limit_cnt; }
ha_rows get_offset_limit() ha_rows get_offset_limit() const
{ return offset_limit_cnt; } { return offset_limit_cnt; }
}; };

View File

@ -4396,7 +4396,7 @@ mysql_execute_command(THD *thd)
if (lex->ignore) if (lex->ignore)
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_UPDATE_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); unit->set_limit(select_lex);
MYSQL_UPDATE_START(thd->query()); MYSQL_UPDATE_START(thd->query());
res= up_result= mysql_update(thd, all_tables, res= up_result= mysql_update(thd, all_tables,
@ -4772,7 +4772,7 @@ mysql_execute_command(THD *thd)
if ((res= delete_precheck(thd, all_tables))) if ((res= delete_precheck(thd, all_tables)))
break; break;
DBUG_ASSERT(select_lex->offset_limit == 0); DBUG_ASSERT(select_lex->limit_params.offset_limit == 0);
unit->set_limit(select_lex); unit->set_limit(select_lex);
MYSQL_DELETE_START(thd->query()); 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 */ /* assign global limit variable if limit is not given */
{ {
SELECT_LEX *param= lex->unit.global_parameters(); SELECT_LEX *param= lex->unit.global_parameters();
if (!param->explicit_limit) if (!param->limit_params.explicit_limit)
param->select_limit= param->limit_params.select_limit=
new (thd->mem_root) Item_int(thd, new (thd->mem_root) Item_int(thd,
(ulonglong) thd->variables.select_limit); (ulonglong) thd->variables.select_limit);
} }
@ -7761,7 +7761,7 @@ void mysql_init_multi_delete(LEX *lex)
{ {
lex->sql_command= SQLCOM_DELETE_MULTI; lex->sql_command= SQLCOM_DELETE_MULTI;
mysql_init_select(lex); 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->unit.lim.set_unlimited();
lex->first_select_lex()->table_list. lex->first_select_lex()->table_list.
save_and_clear(&lex->auxiliary_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->parent_lex= thd_arg->lex; /* Used in init_query. */
fake_select_lex->make_empty_select(); fake_select_lex->make_empty_select();
fake_select_lex->set_linkage(GLOBAL_OPTIONS_TYPE); fake_select_lex->set_linkage(GLOBAL_OPTIONS_TYPE);
fake_select_lex->select_limit= 0;
fake_select_lex->no_table_names_allowed= 1; fake_select_lex->no_table_names_allowed= 1;

View File

@ -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 bool test_if_subpart(ORDER *a,ORDER *b);
static TABLE *get_sort_by_table(ORDER *a,ORDER *b,List<TABLE_LIST> &tables, static TABLE *get_sort_by_table(ORDER *a,ORDER *b,List<TABLE_LIST> &tables,
table_map const_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 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 // Create list for using with tempory table
static bool change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array, static bool change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &new_list1, List<Item> &new_list1,
@ -22034,7 +22035,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{ {
join->do_send_rows= 0; join->do_send_rows= 0;
if (join->unit->fake_select_lex) 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); DBUG_RETURN(NESTED_LOOP_OK);
} }
} }

View File

@ -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() bool table_value_constr::to_be_wrapped_as_with_tail()
{ {
return select_lex->master_unit()->first_select()->next_select() && 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; return NULL;
wrapper_sl->order_list= tvc_sl->order_list; wrapper_sl->order_list= tvc_sl->order_list;
wrapper_sl->select_limit= tvc_sl->select_limit; wrapper_sl->limit_params= tvc_sl->limit_params;
wrapper_sl->offset_limit= tvc_sl->offset_limit;
wrapper_sl->braces= tvc_sl->braces; wrapper_sl->braces= tvc_sl->braces;
wrapper_sl->explicit_limit= tvc_sl->explicit_limit;
tvc_sl->order_list.empty(); tvc_sl->order_list.empty();
tvc_sl->select_limit= NULL; tvc_sl->limit_params.clear();
tvc_sl->offset_limit= NULL;
tvc_sl->braces= 0; tvc_sl->braces= 0;
tvc_sl->explicit_limit= false;
if (tvc_sl->select_number == 1) if (tvc_sl->select_number == 1)
{ {
tvc_sl->select_number= wrapper_sl->select_number; tvc_sl->select_number= wrapper_sl->select_number;

View File

@ -1083,7 +1083,8 @@ bool st_select_lex_unit::prepare_join(THD *thd_arg, SELECT_LEX *sl,
thd_arg->lex->current_select= 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, saved_error= join->prepare(sl->table_list.first,
(derived && derived->merged ? NULL : sl->where), (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)
{ {
if (fake_select_lex->order_list.first || 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), my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"global ORDER_BY/LIMIT in recursive CTE spec"); "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->first_select()->next_select())
{ {
if (!unit->fake_select_lex) if (!unit->fake_select_lex)
{ {
Query_arena *arena, backup_arena; Query_arena *arena, backup_arena;
arena= thd->activate_stmt_arena_if_needed(&backup_arena); arena= thd->activate_stmt_arena_if_needed(&backup_arena);
bool rc= unit->add_fake_select_lex(thd); 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; SELECT_LEX *fake= unit->fake_select_lex;
fake->order_list= sl->order_list; fake->order_list= sl->order_list;
fake->explicit_limit= sl->explicit_limit; fake->limit_params= sl->limit_params;
fake->select_limit= sl->select_limit;
fake->offset_limit= sl->offset_limit;
sl->order_list.empty(); sl->order_list.empty();
sl->explicit_limit= 0; sl->limit_params.clear();
sl->select_limit= 0;
sl->offset_limit= 0;
if (describe) if (describe)
fake->options|= SELECT_DESCRIBE; fake->options|= SELECT_DESCRIBE;
} }
else if (!sl->explicit_limit) else if (!sl->limit_params.explicit_limit)
sl->order_list.empty(); sl->order_list.empty();
} }
} }

View File

@ -1936,7 +1936,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
*/ */
if ((!view->view && !view->belong_to_view) || if ((!view->view && !view->belong_to_view) ||
thd->lex->sql_command == SQLCOM_INSERT || 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 */ DBUG_RETURN(FALSE); /* it is normal table or query without LIMIT */
table= view->table; table= view->table;
view= view->top_table(); view= view->top_table();

View File

@ -10943,13 +10943,11 @@ sum_expr:
Item_func_group_concat(thd, Lex->current_context(), Item_func_group_concat(thd, Lex->current_context(),
$3, $5, $3, $5,
sel->gorder_list, $7, $8, sel->gorder_list, $7, $8,
sel->select_limit, sel->limit_params.select_limit,
sel->offset_limit); sel->limit_params.offset_limit);
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
sel->select_limit= NULL; sel->limit_params.clear();
sel->offset_limit= NULL;
sel->explicit_limit= 0;
$5->empty(); $5->empty();
sel->gorder_list.empty(); sel->gorder_list.empty();
} }
@ -10975,13 +10973,11 @@ sum_expr:
Item_func_json_arrayagg(thd, Lex->current_context(), Item_func_json_arrayagg(thd, Lex->current_context(),
$3, args, $3, args,
sel->gorder_list, s, $7, sel->gorder_list, s, $7,
sel->select_limit, sel->limit_params.select_limit,
sel->offset_limit); sel->limit_params.offset_limit);
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
sel->select_limit= NULL; sel->limit_params.clear();
sel->offset_limit= NULL;
sel->explicit_limit= 0;
$5->empty(); $5->empty();
sel->gorder_list.empty(); sel->gorder_list.empty();
} }
@ -11308,38 +11304,18 @@ opt_glimit_clause:
| glimit_clause { $$ = 1; } | glimit_clause { $$ = 1; }
; ;
glimit_clause_init:
LIMIT{}
;
glimit_clause: glimit_clause:
glimit_clause_init glimit_options LIMIT glimit_options
{ {
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT); Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
} }
; ;
glimit_options: glimit_options:
limit_option limit_options
{ {
SELECT_LEX *sel= Select; Select->limit_params= $1;
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;
} }
; ;
@ -12478,14 +12454,15 @@ order_list:
; ;
order_dir: order_dir:
/* empty */ { $$ = 1; } /* empty */ { $$= 1; }
| ASC { $$ =1; } | ASC { $$= 1; }
| DESC { $$ =0; } | DESC { $$= 0; }
; ;
opt_limit_clause: opt_limit_clause:
/* empty */ /* empty */
{ $$.empty(); } { $$.clear(); }
| limit_clause | limit_clause
{ $$= $1; } { $$= $1; }
; ;
@ -12506,9 +12483,7 @@ limit_clause:
} }
| LIMIT ROWS_SYM EXAMINED_SYM limit_rows_option | LIMIT ROWS_SYM EXAMINED_SYM limit_rows_option
{ {
$$.select_limit= 0; $$.clear();
$$.offset_limit= 0;
$$.explicit_limit= 0;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT); Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
} }
; ;
@ -12516,9 +12491,7 @@ limit_clause:
opt_global_limit_clause: opt_global_limit_clause:
opt_limit_clause opt_limit_clause
{ {
Select->explicit_limit= $1.explicit_limit; Select->limit_params= $1;
Select->select_limit= $1.select_limit;
Select->offset_limit= $1.offset_limit;
} }
; ;
@ -12581,8 +12554,7 @@ limit_option:
limit_rows_option: limit_rows_option:
limit_option limit_option
{ {
LEX *lex=Lex; Lex->limit_rows_examined= $1;
lex->limit_rows_examined= $1;
} }
; ;
@ -12590,14 +12562,14 @@ delete_limit_clause:
/* empty */ /* empty */
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->current_select->select_limit= 0; lex->current_select->limit_params.select_limit= 0;
} }
| LIMIT limit_option | LIMIT limit_option
{ {
SELECT_LEX *sel= Select; SELECT_LEX *sel= Select;
sel->select_limit= $2; sel->limit_params.select_limit= $2;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT); 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 ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; }
| LIMIT limit_option 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 (!$$) if (!$$)
YYABORT; YYABORT;
$$->order_list= NULL; $$->order_list= NULL;
$$->limit.empty(); $$->limit.clear();
$$->lock= $1; $$->lock= $1;
} }
; ;
@ -12674,11 +12646,9 @@ order_or_limit:
} }
| limit_clause | limit_clause
{ {
Lex_order_limit_lock *op= $$= new(thd->mem_root) Lex_order_limit_lock; $$= new(thd->mem_root) Lex_order_limit_lock;
if (!$$) if (!$$)
YYABORT; YYABORT;
op->order_list= NULL;
op->limit= $1;
$$->order_list= NULL; $$->order_list= NULL;
$$->limit= $1; $$->limit= $1;
} }
@ -17028,6 +16998,7 @@ handler_tail:
| table_ident_nodb READ_SYM | table_ident_nodb READ_SYM
{ {
LEX *lex=Lex; LEX *lex=Lex;
SELECT_LEX *select= Select;
if (unlikely(lex->sphead)) if (unlikely(lex->sphead))
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER")); my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER"));
lex->clause_that_disallows_subselect= "HANDLER..READ"; lex->clause_that_disallows_subselect= "HANDLER..READ";
@ -17036,8 +17007,8 @@ handler_tail:
Item *one= new (thd->mem_root) Item_int(thd, (int32) 1); Item *one= new (thd->mem_root) Item_int(thd, (int32) 1);
if (unlikely(one == NULL)) if (unlikely(one == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
lex->current_select->select_limit= one; select->limit_params.select_limit= one;
lex->current_select->offset_limit= 0; select->limit_params.offset_limit= 0;
lex->limit_rows_examined= 0; lex->limit_rows_examined= 0;
if (!lex->current_select->add_table_to_list(thd, $1, 0, 0)) if (!lex->current_select->add_table_to_list(thd, $1, 0, 0))
MYSQL_YYABORT; MYSQL_YYABORT;
@ -17045,14 +17016,15 @@ handler_tail:
handler_read_or_scan opt_where_clause opt_global_limit_clause handler_read_or_scan opt_where_clause opt_global_limit_clause
{ {
LEX *lex=Lex; LEX *lex=Lex;
SELECT_LEX *select= Select;
lex->clause_that_disallows_subselect= NULL; 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); Item *one= new (thd->mem_root) Item_int(thd, (int32) 1);
if (one == NULL) if (one == NULL)
MYSQL_YYABORT; MYSQL_YYABORT;
lex->current_select->select_limit= one; select->limit_params.select_limit= one;
lex->current_select->offset_limit= 0; select->limit_params.offset_limit= 0;
lex->limit_rows_examined= 0; lex->limit_rows_examined= 0;
} }
/* Stored functions are not supported for HANDLER READ. */ /* Stored functions are not supported for HANDLER READ. */

View File

@ -824,13 +824,15 @@ public:
class Lex_select_limit class Lex_select_limit
{ {
public: public:
/* explicit LIMIT clause was used */
bool explicit_limit; bool explicit_limit;
Item *select_limit, *offset_limit; Item *select_limit, *offset_limit;
void empty() void clear()
{ {
explicit_limit= FALSE; explicit_limit= FALSE; // No explicit limit given by user
select_limit= offset_limit= NULL; select_limit= NULL; // denotes the default limit = HA_POS_ERROR
offset_limit= NULL; // denotes the default offset = 0
} }
}; };

View File

@ -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) && !MRN_SELECT_LEX_GET_HAVING_COND(select_lex) &&
select_lex->table_list.elements == 1 && select_lex->table_list.elements == 1 &&
select_lex->order_list.elements && select_lex->order_list.elements &&
select_lex->explicit_limit && select_lex->limit_params.explicit_limit &&
select_lex->select_limit && select_lex->limit_params.select_limit &&
select_lex->select_limit->val_int() > 0 select_lex->limit_params.select_limit->val_int() > 0
) { ) {
if (select_lex->offset_limit) { if (select_lex->limit_params.offset_limit) {
*limit = select_lex->offset_limit->val_int(); *limit = select_lex->limit_params.offset_limit->val_int();
} else { } else {
*limit = 0; *limit = 0;
} }
*limit += select_lex->select_limit->val_int(); *limit += select_lex->limit_params.select_limit->val_int();
if (*limit > (longlong)INT_MAX) { if (*limit > (longlong)INT_MAX) {
DBUG_PRINT("info", DBUG_PRINT("info",
("mroonga: fast_order_limit = false: " ("mroonga: fast_order_limit = false: "

View File

@ -13937,7 +13937,7 @@ void ha_spider::check_pre_call(
select_lex, &select_limit, &offset_limit); select_lex, &select_limit, &offset_limit);
if ( if (
select_lex && select_lex &&
(!select_lex->explicit_limit || !select_limit) (!select_lex->limit_params.explicit_limit || !select_limit)
) { ) {
use_pre_call = TRUE; use_pre_call = TRUE;
} }

View File

@ -1256,7 +1256,7 @@ int spider_group_by_handler::init_scan()
share->direct_order_limit); share->direct_order_limit);
if ( if (
direct_order_limit && direct_order_limit &&
select_lex->explicit_limit && select_lex->limit_params.explicit_limit &&
!(select_lex->options & OPTION_FOUND_ROWS) && !(select_lex->options & OPTION_FOUND_ROWS) &&
select_limit < direct_order_limit /* - offset_limit */ 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->internal_limit >= result_list->split_read ?
result_list->split_read : result_list->internal_limit; 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; result_list->internal_offset += offset_limit;
} else { } else {

View File

@ -8961,12 +8961,12 @@ void spider_get_select_limit_from_select_lex(
DBUG_ENTER("spider_get_select_limit_from_select_lex"); DBUG_ENTER("spider_get_select_limit_from_select_lex");
*select_limit = 9223372036854775807LL; *select_limit = 9223372036854775807LL;
*offset_limit = 0; *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_limit = select_lex->limit_params.select_limit ?
select_lex->select_limit->val_int() : 0; select_lex->limit_params.select_limit->val_int() : 0;
*offset_limit = select_lex->offset_limit ? *offset_limit = select_lex->limit_params.offset_limit ?
select_lex->offset_limit->val_int() : 0; select_lex->limit_params.offset_limit->val_int() : 0;
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -9158,13 +9158,13 @@ longlong spider_split_read_param(
result_list->set_split_read = TRUE; 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 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 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->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")); DBUG_PRINT("info",("spider select_lex->with_sum_func=%s", select_lex && select_lex->with_sum_func ? "TRUE" : "FALSE"));
if ( if (
result_list->semi_split_read > 0 && 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->options & OPTION_FOUND_ROWS) &&
!select_lex->group_list.elements && !select_lex->group_list.elements &&
!select_lex->with_sum_func !select_lex->with_sum_func
@ -9394,7 +9394,7 @@ bool spider_check_direct_order_limit(
select_lex ? select_lex->order_list.elements : 0)); select_lex ? select_lex->order_list.elements : 0));
if ( if (
!first_check || !first_check ||
!select_lex->explicit_limit || !select_lex->limit_params.explicit_limit ||
(select_lex->options & OPTION_FOUND_ROWS) || (select_lex->options & OPTION_FOUND_ROWS) ||
( (
#ifdef HANDLER_HAS_DIRECT_AGGREGATE #ifdef HANDLER_HAS_DIRECT_AGGREGATE