From f28b5e6e910a48d70eb836c6c606fa2b7ba776bc Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 21 Nov 2003 21:19:56 +0200 Subject: [PATCH] limit initialization moved to method of SELECT_LEX_UNIT (WL#695) (SCRUM) counters was not moved to SELECT_LEX because it used in methods inherited from select_result which should be applied to whole union results mysql-test/r/union.result: this is results is true sql/item_subselect.cc: limit initialization moved to method of SELECT_LEX_UNIT sql/sql_derived.cc: limit initialization moved to method of SELECT_LEX_UNIT sql/sql_lex.cc: limit initialization moved to method of SELECT_LEX_UNIT sql/sql_lex.h: limit initialization moved to method of SELECT_LEX_UNIT sql/sql_parse.cc: limit initialization moved to handle_select for single select (UNIONs already have it) sql/sql_select.cc: limit initialization moved to method of SELECT_LEX_UNIT sql/sql_union.cc: layout fixed limit initialization moved to method of SELECT_LEX_UNIT --- mysql-test/r/union.result | 4 ++-- sql/item_subselect.cc | 10 +++------- sql/sql_derived.cc | 10 +++------- sql/sql_lex.cc | 12 ++++++++++++ sql/sql_lex.h | 2 ++ sql/sql_parse.cc | 19 ++----------------- sql/sql_select.cc | 27 +++++++++++++++++++-------- sql/sql_union.cc | 33 +++++++++++++++------------------ 8 files changed, 58 insertions(+), 59 deletions(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 00eddd596cf..e42c3e01b25 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -123,8 +123,8 @@ id select_type table type possible_keys key key_len ref rows Extra 3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used explain select a,b from t1 union select 1 limit 0; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 UNION NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used select a,b from t1 into outfile 'skr' union select a,b from t2; ERROR HY000: Wrong usage of UNION and INTO select a,b from t1 order by a union select a,b from t2; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 3ed137d0731..3fcda8ca507 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -876,13 +876,9 @@ subselect_single_select_engine(st_select_lex *select, { select_lex= select; SELECT_LEX_UNIT *unit= select_lex->master_unit(); - unit->offset_limit_cnt= unit->global_parameters->offset_limit; - unit->select_limit_cnt= unit->global_parameters->select_limit+ - unit->global_parameters ->offset_limit; - if (unit->select_limit_cnt < unit->global_parameters->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // no limit - if (unit->select_limit_cnt == HA_POS_ERROR) - select_lex->options&= ~OPTION_FOUND_ROWS; + unit->set_limit(unit->global_parameters->select_limit, + unit->global_parameters->offset_limit, + select_lex); unit->item= item; this->select_lex= select_lex; } diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 719686a56c3..964b8da728d 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -168,13 +168,9 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, if ((derived_result=new select_union(table))) { derived_result->tmp_table_param=tmp_table_param; - unit->offset_limit_cnt= select_cursor->offset_limit; - unit->select_limit_cnt= select_cursor->select_limit+ - select_cursor->offset_limit; - if (unit->select_limit_cnt < select_cursor->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; - if (unit->select_limit_cnt == HA_POS_ERROR) - select_cursor->options&= ~OPTION_FOUND_ROWS; + unit->set_limit(select_cursor->select_limit, + select_cursor->offset_limit, + select_cursor); if (is_union) res= mysql_union(thd, lex, derived_result, unit, 1); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 6ed8d23ab95..232e1d5d8d0 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1008,6 +1008,7 @@ void st_select_lex_unit::init_query() union_result= 0; table= 0; fake_select_lex= 0; + found_rows_for_union= 0; } void st_select_lex::init_query() @@ -1609,6 +1610,17 @@ void st_select_lex::print_limit(THD *thd, String *str) } } +void st_select_lex_unit::set_limit(ha_rows limit, ha_rows offset, + SELECT_LEX *sl) +{ + offset_limit_cnt= offset; + select_limit_cnt= limit+offset; + if (select_limit_cnt < limit) + select_limit_cnt= HA_POS_ERROR; // no limit + if (select_limit_cnt == HA_POS_ERROR) + sl->options&= ~OPTION_FOUND_ROWS; +} + /* There are st_select_lex::add_table_to_list & st_select_lex::set_lock_for_tables in sql_parse.cc diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 8f879f12b10..93ae78c52e5 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -359,6 +359,8 @@ public: void print(String *str); + void set_limit(ha_rows limit, ha_rows offset, st_select_lex *sl); + friend void mysql_init_query(THD *thd, bool lexonly); friend int subselect_union_engine::exec(); private: diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index bb9f48231d7..af969cb11a4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1843,18 +1843,6 @@ mysql_execute_command(THD *thd) break; // Error message is given } #endif - /* - In case of single SELECT unit->global_parameters points on first SELECT - TODO: move counters to SELECT_LEX - */ - unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit; - unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+ - unit->global_parameters->offset_limit); - if (unit->select_limit_cnt < - (ha_rows) unit->global_parameters->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // no limit - if (unit->select_limit_cnt == HA_POS_ERROR && !select_lex->next_select()) - select_lex->options&= ~OPTION_FOUND_ROWS; if (!(res=open_and_lock_tables(thd,tables))) { @@ -2188,11 +2176,8 @@ mysql_execute_command(THD *thd) } #endif select_lex->options|= SELECT_NO_UNLOCK; - unit->offset_limit_cnt= select_lex->offset_limit; - unit->select_limit_cnt= select_lex->select_limit+ - select_lex->offset_limit; - if (unit->select_limit_cnt < select_lex->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // No limit + unit->set_limit(select_lex->select_limit, select_lex->offset_limit, + select_lex); /* Skip first table, which is the table we are creating */ lex->select_lex.table_list.first= diff --git a/sql/sql_select.cc b/sql/sql_select.cc index eea5ed72a3a..5ee598e3951 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -177,8 +177,13 @@ int handle_select(THD *thd, LEX *lex, select_result *result) fix_tables_pointers(lex->all_selects_list); if (select_lex->next_select()) - res=mysql_union(thd, lex, result, &lex->unit, 0); + res= mysql_union(thd, lex, result, &lex->unit, 0); else + { + SELECT_LEX_UNIT *unit= &lex->unit; + unit->set_limit(unit->global_parameters->select_limit, + unit->global_parameters->offset_limit, + select_lex); res= mysql_select(thd, &select_lex->ref_pointer_array, (TABLE_LIST*) select_lex->table_list.first, select_lex->with_wild, select_lex->item_list, @@ -190,7 +195,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result) select_lex->having, (ORDER*) lex->proc_list.first, select_lex->options | thd->options, - result, &(lex->unit), &(lex->select_lex), 0); + result, unit, select_lex, 0); + } /* Don't set res if it's -1 as we may want this later */ DBUG_PRINT("info",("res: %d report_error: %d", res, @@ -1012,12 +1018,8 @@ JOIN::reinit() { DBUG_ENTER("JOIN::reinit"); /* TODO move to unit reinit */ - unit->offset_limit_cnt =select_lex->offset_limit; - unit->select_limit_cnt =select_lex->select_limit+select_lex->offset_limit; - if (unit->select_limit_cnt < select_lex->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // no limit - if (unit->select_limit_cnt == HA_POS_ERROR) - select_lex->options&= ~OPTION_FOUND_ROWS; + unit->set_limit(select_lex->select_limit, select_lex->offset_limit, + select_lex); if (setup_tables(tables_list)) DBUG_RETURN(1); @@ -9069,6 +9071,15 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type, select_lex->type= type; thd->lex->current_select= select_lex; SELECT_LEX_UNIT *unit= select_lex->master_unit(); + if (select_lex == unit->global_parameters && + unit->first_select()->next_select()) + { + unit->offset_limit_cnt= 0; + unit->select_limit_cnt= HA_POS_ERROR; + } + else + unit->set_limit(select_lex->select_limit, select_lex->offset_limit, + select_lex); int res= mysql_select(thd, &select_lex->ref_pointer_array, (TABLE_LIST*) select_lex->table_list.first, select_lex->with_wild, select_lex->item_list, diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 4234eba8a14..d9fb13ac59b 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -130,11 +130,13 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, prepared= 1; res= 0; found_rows_for_union= first_select_in_union()->options & OPTION_FOUND_ROWS; + TMP_TABLE_PARAM tmp_table_param; t_and_f= tables_and_fields_initied; bzero((char *)&tmp_table_param,sizeof(TMP_TABLE_PARAM)); thd->lex->current_select= sl= select_cursor= first_select_in_union(); + /* Global option */ if (t_and_f) { @@ -198,11 +200,8 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, sl->options | thd->options | SELECT_NO_UNLOCK, union_result); thd->lex->current_select= sl; - offset_limit_cnt= sl->offset_limit; - select_limit_cnt= sl->select_limit+sl->offset_limit; - if (select_limit_cnt < sl->select_limit) - select_limit_cnt= HA_POS_ERROR; // no limit - if (select_limit_cnt == HA_POS_ERROR || sl->braces) + set_limit(sl->select_limit, sl->offset_limit, sl); + if (sl->braces) sl->options&= ~OPTION_FOUND_ROWS; res= join->prepare(&sl->ref_pointer_array, @@ -372,18 +371,15 @@ int st_select_lex_unit::exec() if (!thd->is_fatal_error) // Check if EOM { - ulong options= thd->options; thd->lex->current_select= fake_select_lex; - offset_limit_cnt= global_parameters->offset_limit; - select_limit_cnt= global_parameters->select_limit + - global_parameters->offset_limit; + fake_select_lex->options= thd->options; + set_limit(global_parameters->select_limit, + global_parameters->offset_limit, + fake_select_lex); - if (select_limit_cnt < global_parameters->select_limit) - select_limit_cnt= HA_POS_ERROR; // no limit - if (select_limit_cnt == HA_POS_ERROR) - options&= ~OPTION_FOUND_ROWS; - else if (found_rows_for_union && !thd->lex->describe) - options|= OPTION_FOUND_ROWS; + if (found_rows_for_union && !thd->lex->describe && + select_limit_cnt != HA_POS_ERROR) + fake_select_lex->options|= OPTION_FOUND_ROWS; fake_select_lex->ftfunc_list= &empty_list; fake_select_lex->table_list.link_in_list((byte *)&result_table_list, (byte **) @@ -395,7 +391,8 @@ int st_select_lex_unit::exec() allocate JOIN for fake select only once (privent mysql_select automatic allocation) */ - fake_select_lex->join= new JOIN(thd, item_list, thd->options, result); + fake_select_lex->join= new JOIN(thd, item_list, + fake_select_lex->options, result); /* Fake st_select_lex should have item list for correctref_array allocation. @@ -410,7 +407,7 @@ int st_select_lex_unit::exec() delete tab->select; delete tab->quick; } - join->init(thd, item_list, thd->options, result); + join->init(thd, item_list, fake_select_lex->options, result); } res= mysql_select(thd, &fake_select_lex->ref_pointer_array, &result_table_list, @@ -418,7 +415,7 @@ int st_select_lex_unit::exec() global_parameters->order_list.elements, (ORDER*)global_parameters->order_list.first, (ORDER*) NULL, NULL, (ORDER*) NULL, - options | SELECT_NO_UNLOCK, + fake_select_lex->options | SELECT_NO_UNLOCK, result, this, fake_select_lex, 0); if (!res) thd->limit_found_rows = (ulonglong)table->file->records + add_rows;