Commit 09cefdd5 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

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
parent 5b355ea6
...@@ -123,8 +123,8 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -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 3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
explain select a,b from t1 union select 1 limit 0; explain select a,b from t1 union select 1 limit 0;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY 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 Impossible WHERE 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; select a,b from t1 into outfile 'skr' union select a,b from t2;
ERROR HY000: Wrong usage of UNION and INTO ERROR HY000: Wrong usage of UNION and INTO
select a,b from t1 order by a union select a,b from t2; select a,b from t1 order by a union select a,b from t2;
......
...@@ -876,13 +876,9 @@ subselect_single_select_engine(st_select_lex *select, ...@@ -876,13 +876,9 @@ subselect_single_select_engine(st_select_lex *select,
{ {
select_lex= select; select_lex= select;
SELECT_LEX_UNIT *unit= select_lex->master_unit(); SELECT_LEX_UNIT *unit= select_lex->master_unit();
unit->offset_limit_cnt= unit->global_parameters->offset_limit; unit->set_limit(unit->global_parameters->select_limit,
unit->select_limit_cnt= unit->global_parameters->select_limit+ unit->global_parameters->offset_limit,
unit->global_parameters ->offset_limit; select_lex);
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->item= item; unit->item= item;
this->select_lex= select_lex; this->select_lex= select_lex;
} }
......
...@@ -168,13 +168,9 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, ...@@ -168,13 +168,9 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
if ((derived_result=new select_union(table))) if ((derived_result=new select_union(table)))
{ {
derived_result->tmp_table_param=tmp_table_param; derived_result->tmp_table_param=tmp_table_param;
unit->offset_limit_cnt= select_cursor->offset_limit; unit->set_limit(select_cursor->select_limit,
unit->select_limit_cnt= select_cursor->select_limit+ select_cursor->offset_limit,
select_cursor->offset_limit; select_cursor);
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;
if (is_union) if (is_union)
res= mysql_union(thd, lex, derived_result, unit, 1); res= mysql_union(thd, lex, derived_result, unit, 1);
......
...@@ -1008,6 +1008,7 @@ void st_select_lex_unit::init_query() ...@@ -1008,6 +1008,7 @@ void st_select_lex_unit::init_query()
union_result= 0; union_result= 0;
table= 0; table= 0;
fake_select_lex= 0; fake_select_lex= 0;
found_rows_for_union= 0;
} }
void st_select_lex::init_query() void st_select_lex::init_query()
...@@ -1609,6 +1610,17 @@ void st_select_lex::print_limit(THD *thd, String *str) ...@@ -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 & There are st_select_lex::add_table_to_list &
st_select_lex::set_lock_for_tables in sql_parse.cc st_select_lex::set_lock_for_tables in sql_parse.cc
......
...@@ -359,6 +359,8 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -359,6 +359,8 @@ class st_select_lex_unit: public st_select_lex_node {
void print(String *str); 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 void mysql_init_query(THD *thd, bool lexonly);
friend int subselect_union_engine::exec(); friend int subselect_union_engine::exec();
private: private:
......
...@@ -1843,18 +1843,6 @@ mysql_execute_command(THD *thd) ...@@ -1843,18 +1843,6 @@ mysql_execute_command(THD *thd)
break; // Error message is given break; // Error message is given
} }
#endif #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))) if (!(res=open_and_lock_tables(thd,tables)))
{ {
...@@ -2188,11 +2176,8 @@ mysql_execute_command(THD *thd) ...@@ -2188,11 +2176,8 @@ mysql_execute_command(THD *thd)
} }
#endif #endif
select_lex->options|= SELECT_NO_UNLOCK; select_lex->options|= SELECT_NO_UNLOCK;
unit->offset_limit_cnt= select_lex->offset_limit; unit->set_limit(select_lex->select_limit, select_lex->offset_limit,
unit->select_limit_cnt= select_lex->select_limit+ select_lex);
select_lex->offset_limit;
if (unit->select_limit_cnt < select_lex->select_limit)
unit->select_limit_cnt= HA_POS_ERROR; // No limit
/* Skip first table, which is the table we are creating */ /* Skip first table, which is the table we are creating */
lex->select_lex.table_list.first= lex->select_lex.table_list.first=
......
...@@ -177,8 +177,13 @@ int handle_select(THD *thd, LEX *lex, select_result *result) ...@@ -177,8 +177,13 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
fix_tables_pointers(lex->all_selects_list); fix_tables_pointers(lex->all_selects_list);
if (select_lex->next_select()) if (select_lex->next_select())
res=mysql_union(thd, lex, result, &lex->unit, 0); res= mysql_union(thd, lex, result, &lex->unit, 0);
else 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, res= mysql_select(thd, &select_lex->ref_pointer_array,
(TABLE_LIST*) select_lex->table_list.first, (TABLE_LIST*) select_lex->table_list.first,
select_lex->with_wild, select_lex->item_list, select_lex->with_wild, select_lex->item_list,
...@@ -190,7 +195,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result) ...@@ -190,7 +195,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
select_lex->having, select_lex->having,
(ORDER*) lex->proc_list.first, (ORDER*) lex->proc_list.first,
select_lex->options | thd->options, 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 */ /* Don't set res if it's -1 as we may want this later */
DBUG_PRINT("info",("res: %d report_error: %d", res, DBUG_PRINT("info",("res: %d report_error: %d", res,
...@@ -1012,12 +1018,8 @@ JOIN::reinit() ...@@ -1012,12 +1018,8 @@ JOIN::reinit()
{ {
DBUG_ENTER("JOIN::reinit"); DBUG_ENTER("JOIN::reinit");
/* TODO move to unit reinit */ /* TODO move to unit reinit */
unit->offset_limit_cnt =select_lex->offset_limit; unit->set_limit(select_lex->select_limit, select_lex->offset_limit,
unit->select_limit_cnt =select_lex->select_limit+select_lex->offset_limit; select_lex);
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;
if (setup_tables(tables_list)) if (setup_tables(tables_list))
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -9069,6 +9071,15 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type, ...@@ -9069,6 +9071,15 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
select_lex->type= type; select_lex->type= type;
thd->lex->current_select= select_lex; thd->lex->current_select= select_lex;
SELECT_LEX_UNIT *unit= select_lex->master_unit(); 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, int res= mysql_select(thd, &select_lex->ref_pointer_array,
(TABLE_LIST*) select_lex->table_list.first, (TABLE_LIST*) select_lex->table_list.first,
select_lex->with_wild, select_lex->item_list, select_lex->with_wild, select_lex->item_list,
......
...@@ -130,11 +130,13 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, ...@@ -130,11 +130,13 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
prepared= 1; prepared= 1;
res= 0; res= 0;
found_rows_for_union= first_select_in_union()->options & OPTION_FOUND_ROWS; found_rows_for_union= first_select_in_union()->options & OPTION_FOUND_ROWS;
TMP_TABLE_PARAM tmp_table_param; TMP_TABLE_PARAM tmp_table_param;
t_and_f= tables_and_fields_initied; t_and_f= tables_and_fields_initied;
bzero((char *)&tmp_table_param,sizeof(TMP_TABLE_PARAM)); bzero((char *)&tmp_table_param,sizeof(TMP_TABLE_PARAM));
thd->lex->current_select= sl= select_cursor= first_select_in_union(); thd->lex->current_select= sl= select_cursor= first_select_in_union();
/* Global option */ /* Global option */
if (t_and_f) if (t_and_f)
{ {
...@@ -198,11 +200,8 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, ...@@ -198,11 +200,8 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
sl->options | thd->options | SELECT_NO_UNLOCK, sl->options | thd->options | SELECT_NO_UNLOCK,
union_result); union_result);
thd->lex->current_select= sl; thd->lex->current_select= sl;
offset_limit_cnt= sl->offset_limit; set_limit(sl->select_limit, sl->offset_limit, sl);
select_limit_cnt= sl->select_limit+sl->offset_limit; if (sl->braces)
if (select_limit_cnt < sl->select_limit)
select_limit_cnt= HA_POS_ERROR; // no limit
if (select_limit_cnt == HA_POS_ERROR || sl->braces)
sl->options&= ~OPTION_FOUND_ROWS; sl->options&= ~OPTION_FOUND_ROWS;
res= join->prepare(&sl->ref_pointer_array, res= join->prepare(&sl->ref_pointer_array,
...@@ -372,18 +371,15 @@ int st_select_lex_unit::exec() ...@@ -372,18 +371,15 @@ int st_select_lex_unit::exec()
if (!thd->is_fatal_error) // Check if EOM if (!thd->is_fatal_error) // Check if EOM
{ {
ulong options= thd->options;
thd->lex->current_select= fake_select_lex; thd->lex->current_select= fake_select_lex;
offset_limit_cnt= global_parameters->offset_limit; fake_select_lex->options= thd->options;
select_limit_cnt= global_parameters->select_limit + set_limit(global_parameters->select_limit,
global_parameters->offset_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 (found_rows_for_union && !thd->lex->describe &&
if (select_limit_cnt == HA_POS_ERROR) select_limit_cnt != HA_POS_ERROR)
options&= ~OPTION_FOUND_ROWS; fake_select_lex->options|= OPTION_FOUND_ROWS;
else if (found_rows_for_union && !thd->lex->describe)
options|= OPTION_FOUND_ROWS;
fake_select_lex->ftfunc_list= &empty_list; fake_select_lex->ftfunc_list= &empty_list;
fake_select_lex->table_list.link_in_list((byte *)&result_table_list, fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
(byte **) (byte **)
...@@ -395,7 +391,8 @@ int st_select_lex_unit::exec() ...@@ -395,7 +391,8 @@ int st_select_lex_unit::exec()
allocate JOIN for fake select only once (privent allocate JOIN for fake select only once (privent
mysql_select automatic allocation) 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 Fake st_select_lex should have item list for correctref_array
allocation. allocation.
...@@ -410,7 +407,7 @@ int st_select_lex_unit::exec() ...@@ -410,7 +407,7 @@ int st_select_lex_unit::exec()
delete tab->select; delete tab->select;
delete tab->quick; 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, res= mysql_select(thd, &fake_select_lex->ref_pointer_array,
&result_table_list, &result_table_list,
...@@ -418,7 +415,7 @@ int st_select_lex_unit::exec() ...@@ -418,7 +415,7 @@ int st_select_lex_unit::exec()
global_parameters->order_list.elements, global_parameters->order_list.elements,
(ORDER*)global_parameters->order_list.first, (ORDER*)global_parameters->order_list.first,
(ORDER*) NULL, NULL, (ORDER*) NULL, (ORDER*) NULL, NULL, (ORDER*) NULL,
options | SELECT_NO_UNLOCK, fake_select_lex->options | SELECT_NO_UNLOCK,
result, this, fake_select_lex, 0); result, this, fake_select_lex, 0);
if (!res) if (!res)
thd->limit_found_rows = (ulonglong)table->file->records + add_rows; thd->limit_found_rows = (ulonglong)table->file->records + add_rows;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment