sql_union.cc:

  Merge fix
parent 84c2e91f
...@@ -31,9 +31,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -31,9 +31,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
ORDER *order; ORDER *order;
List<Item> item_list; List<Item> item_list;
TABLE *table; TABLE *table;
int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0; int res;
int res, add_rows=0; ulonglong add_rows= 0;
bool found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS; ulong found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS;
ulong describe= lex->select_lex.options & SELECT_DESCRIBE;
TABLE_LIST result_table_list; TABLE_LIST result_table_list;
TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first; TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first;
TMP_TABLE_PARAM tmp_table_param; TMP_TABLE_PARAM tmp_table_param;
...@@ -135,20 +136,30 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -135,20 +136,30 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
union_result->tmp_table_param=&tmp_table_param; union_result->tmp_table_param=&tmp_table_param;
for (sl= &lex->select_lex; sl; sl=sl->next) for (sl= &lex->select_lex; sl; sl=sl->next)
{ {
unsigned int rows; ha_rows records_at_start;
lex->select=sl; lex->select=sl;
thd->offset_limit=sl->offset_limit; /* Don't use offset for the last union if there is no braces */
thd->offset_limit= sl != lex_sl ? sl->offset_limit : 0;
thd->select_limit=sl->select_limit+sl->offset_limit; thd->select_limit=sl->select_limit+sl->offset_limit;
if (thd->select_limit < sl->select_limit) if (thd->select_limit < sl->select_limit)
thd->select_limit= HA_POS_ERROR; // no limit thd->select_limit= 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 (thd->select_limit == HA_POS_ERROR || sl->braces) if (thd->select_limit == HA_POS_ERROR || sl->braces)
sl->options&= ~OPTION_FOUND_ROWS; sl->options&= ~OPTION_FOUND_ROWS;
else if (found_rows_for_union) else
{ {
rows= thd->select_limit; /*
sl->options|= OPTION_FOUND_ROWS; We are doing an union without braces. In this case
SQL_CALC_FOUND_ROWS should be done on all sub parts
*/
sl->options|= found_rows_for_union;
} }
records_at_start= table->file->records;
res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ? res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ?
first_table : (TABLE_LIST*) sl->table_list.first, first_table : (TABLE_LIST*) sl->table_list.first,
sl->item_list, sl->item_list,
...@@ -159,12 +170,23 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -159,12 +170,23 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
sl->having, sl->having,
(ORDER*) NULL, (ORDER*) NULL,
sl->options | thd->options | SELECT_NO_UNLOCK | sl->options | thd->options | SELECT_NO_UNLOCK |
((describe) ? SELECT_DESCRIBE : 0), describe,
union_result); union_result);
if (found_rows_for_union && !sl->braces && sl->options & OPTION_FOUND_ROWS)
add_rows+= (thd->limit_found_rows > rows) ? thd->limit_found_rows - rows : 0;
if (res) if (res)
goto exit; goto exit;
/* 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.
We get this from the difference of between total number of possible
rows and actual rows added to the temporary table.
*/
add_rows+= (ulonglong) (thd->limit_found_rows - (table->file->records -
records_at_start));
}
} }
if (union_result->flush()) if (union_result->flush())
{ {
...@@ -217,12 +239,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -217,12 +239,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
item_list, NULL, (describe) ? 0 : order, item_list, NULL, (describe) ? 0 : order,
(ORDER*) NULL, NULL, (ORDER*) NULL, (ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result); thd->options, result);
if (found_rows_for_union && !res) if (!res)
{ thd->limit_found_rows = (ulonglong)table->file->records + add_rows;
thd->limit_found_rows= table->file->records;
if (!last_sl->braces)
thd->limit_found_rows+= 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