sql_union.cc:
Merge fix
This commit is contained in:
parent
84c2e91f1e
commit
e5b841e392
@ -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,19 +136,29 @@ 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,
|
||||||
@ -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)
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user