diff options
Diffstat (limited to 'sql/sql_union.cc')
-rw-r--r-- | sql/sql_union.cc | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 24497589c73..2b10fe2cd2a 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -123,8 +123,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, DBUG_RETURN(0); prepared= 1; res= 0; - found_rows_for_union= test(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; result= sel_result; t_and_f= tables_and_fields_initied; @@ -239,7 +238,7 @@ int st_select_lex_unit::exec() { SELECT_LEX *lex_select_save= thd->lex.current_select; SELECT_LEX *select_cursor=first_select_in_union(); - ha_rows add_rows=0; + ulonglong add_rows=0; DBUG_ENTER("st_select_lex_unit::exec"); if (executed && !(dependent || uncacheable)) @@ -263,10 +262,30 @@ int st_select_lex_unit::exec() res= sl->join->reinit(); else { - offset_limit_cnt= sl->offset_limit; - select_limit_cnt= sl->select_limit+sl->offset_limit; + /* Don't use offset for the last union if there is no braces */ + if (sl != lex_sl) + { + offset_limit_cnt= sl->offset_limit; + select_limit_cnt= sl->select_limit+sl->offset_limit; + } + else + { + offset_limit_cnt= 0; + /* + We can't use LIMIT at this stage if we are using ORDER BY for the + whole query + */ + select_limit_cnt= HA_POS_ERROR; + if (! sl->order_list.first) + select_limit_cnt= sl->select_limit+sl->offset_limit; + } if (select_limit_cnt < sl->select_limit) select_limit_cnt= HA_POS_ERROR; // no limit + + /* + When using braces, SQL_CALC_FOUND_ROWS affects the whole query. + We don't calculate found_rows() per union part + */ if (select_limit_cnt == HA_POS_ERROR || sl->braces) sl->options&= ~OPTION_FOUND_ROWS; else @@ -318,11 +337,13 @@ int st_select_lex_unit::exec() thd->lex.current_select= lex_select_save; DBUG_RETURN(res); } + /* Needed for the following test and for records_at_start in next loop */ + table->file->info(HA_STATUS_VARIABLE); if (found_rows_for_union & sl->options) { /* - This is a union without braces. Remember the number of rows that could - also have been part of the result set. + This is a union without braces. Remember the number of rows that + could also have been part of the result set. We get this from the difference of between total number of possible rows and actual rows added to the temporary table. */ @@ -341,7 +362,7 @@ int st_select_lex_unit::exec() List<Item_func_match> empty_list; empty_list.empty(); - 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; |