diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2020-12-19 13:59:37 +0200 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2021-04-21 14:08:58 +0300 |
commit | 13cf8f5e9afc7f64df79b41e2b004c28086371f4 (patch) | |
tree | ed6bfed9c8488ab688b57bafa42e7eaa68ae2168 | |
parent | dd6ad3806856221f1af302e61ebd985905a00060 (diff) | |
download | mariadb-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.cc | 2 | ||||
-rw-r--r-- | sql/ha_partition.cc | 14 | ||||
-rw-r--r-- | sql/item_subselect.cc | 26 | ||||
-rw-r--r-- | sql/opt_subselect.cc | 6 | ||||
-rw-r--r-- | sql/sql_derived.cc | 3 | ||||
-rw-r--r-- | sql/sql_lex.cc | 46 | ||||
-rw-r--r-- | sql/sql_lex.h | 9 | ||||
-rw-r--r-- | sql/sql_limit.h | 8 | ||||
-rw-r--r-- | sql/sql_parse.cc | 11 | ||||
-rw-r--r-- | sql/sql_select.cc | 7 | ||||
-rw-r--r-- | sql/sql_tvc.cc | 11 | ||||
-rw-r--r-- | sql/sql_union.cc | 17 | ||||
-rw-r--r-- | sql/sql_view.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 86 | ||||
-rw-r--r-- | sql/structs.h | 8 | ||||
-rw-r--r-- | storage/mroonga/ha_mroonga.cpp | 12 | ||||
-rw-r--r-- | storage/spider/ha_spider.cc | 2 | ||||
-rw-r--r-- | storage/spider/spd_group_by_handler.cc | 4 | ||||
-rw-r--r-- | storage/spider/spd_table.cc | 16 |
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 |