mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
union.result:
same as above sql_lex.h: same as above sql_union.cc: same as aobve sql_select.cc: Fixing that SQL_CALC_FOUND_ROWS work properly in UNION's in 4.1 Plus updating some fields in THD in the proper places plus fixing a wrong result sql/sql_select.cc: Fixing that SQL_CALC_FOUND_ROWS work properly in UNION's in 4.1 Plus updating some fields in THD in the proper places plus fixing a wrong result sql/sql_union.cc: same as aobve sql/sql_lex.h: same as above mysql-test/r/union.result: same as above
This commit is contained in:
@ -103,7 +103,7 @@ a b
|
|||||||
2 b
|
2 b
|
||||||
select found_rows();
|
select found_rows();
|
||||||
found_rows()
|
found_rows()
|
||||||
6
|
8
|
||||||
explain select a,b from t1 union all select a,b from t2;
|
explain select a,b from t1 union all select a,b from t2;
|
||||||
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 t1 ALL NULL NULL NULL NULL 4
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
|
||||||
|
@ -290,8 +290,8 @@ protected:
|
|||||||
|
|
||||||
select_result *result;
|
select_result *result;
|
||||||
int res;
|
int res;
|
||||||
bool describe, found_rows_for_union,
|
ulong describe, found_rows_for_union;
|
||||||
prepared, // prepare phase already performed for UNION (unit)
|
bool prepared, // prepare phase already performed for UNION (unit)
|
||||||
optimized, // optimize phase already performed for UNION (unit)
|
optimized, // optimize phase already performed for UNION (unit)
|
||||||
executed, // already executed
|
executed, // already executed
|
||||||
t_and_f; // used for transferring tables_and_fields_initied UNIT:: methods
|
t_and_f; // used for transferring tables_and_fields_initied UNIT:: methods
|
||||||
|
@ -941,6 +941,7 @@ JOIN::exec()
|
|||||||
DBUG_ENTER("JOIN::exec");
|
DBUG_ENTER("JOIN::exec");
|
||||||
|
|
||||||
error= 0;
|
error= 0;
|
||||||
|
thd->limit_found_rows= thd->examined_row_count= 0;
|
||||||
if (procedure)
|
if (procedure)
|
||||||
{
|
{
|
||||||
if (procedure->change_columns(fields_list) ||
|
if (procedure->change_columns(fields_list) ||
|
||||||
@ -1323,6 +1324,8 @@ JOIN::exec()
|
|||||||
thd->proc_info="Sending data";
|
thd->proc_info="Sending data";
|
||||||
error= thd->net.report_error ||
|
error= thd->net.report_error ||
|
||||||
do_select(curr_join, curr_fields_list, NULL, procedure);
|
do_select(curr_join, curr_fields_list, NULL, procedure);
|
||||||
|
thd->limit_found_rows= curr_join->send_records;
|
||||||
|
thd->examined_row_count= curr_join->examined_rows;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1434,8 +1437,6 @@ err:
|
|||||||
(join->tmp_join->error=join->error,join->tmp_join):
|
(join->tmp_join->error=join->error,join->tmp_join):
|
||||||
join);
|
join);
|
||||||
|
|
||||||
thd->limit_found_rows= curr_join->send_records;
|
|
||||||
thd->examined_row_count= curr_join->examined_rows;
|
|
||||||
thd->proc_info="end";
|
thd->proc_info="end";
|
||||||
err= join->cleanup();
|
err= join->cleanup();
|
||||||
if (thd->net.report_error)
|
if (thd->net.report_error)
|
||||||
|
@ -204,7 +204,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
|
|||||||
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
||||||
if (select_limit_cnt < sl->select_limit)
|
if (select_limit_cnt < sl->select_limit)
|
||||||
select_limit_cnt= HA_POS_ERROR; // no limit
|
select_limit_cnt= HA_POS_ERROR; // no limit
|
||||||
if (select_limit_cnt == HA_POS_ERROR && !sl->braces)
|
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,
|
||||||
@ -249,7 +249,7 @@ int st_select_lex_unit::exec()
|
|||||||
{
|
{
|
||||||
SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
|
SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
|
||||||
SELECT_LEX *select_cursor=first_select_in_union();
|
SELECT_LEX *select_cursor=first_select_in_union();
|
||||||
unsigned int add_rows=0;
|
ulonglong add_rows=0;
|
||||||
DBUG_ENTER("st_select_lex_unit::exec");
|
DBUG_ENTER("st_select_lex_unit::exec");
|
||||||
|
|
||||||
if (executed && !(dependent || uncacheable))
|
if (executed && !(dependent || uncacheable))
|
||||||
@ -266,7 +266,7 @@ int st_select_lex_unit::exec()
|
|||||||
}
|
}
|
||||||
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
||||||
{
|
{
|
||||||
unsigned int rows;
|
ha_rows records_at_start;
|
||||||
if (optimized)
|
if (optimized)
|
||||||
res= sl->join->reinit();
|
res= sl->join->reinit();
|
||||||
else
|
else
|
||||||
@ -279,12 +279,15 @@ int st_select_lex_unit::exec()
|
|||||||
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
||||||
if (select_limit_cnt < sl->select_limit)
|
if (select_limit_cnt < sl->select_limit)
|
||||||
select_limit_cnt= HA_POS_ERROR; // no limit
|
select_limit_cnt= HA_POS_ERROR; // no limit
|
||||||
if (select_limit_cnt == HA_POS_ERROR)
|
if (select_limit_cnt == 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
res= join->prepare(&sl->ref_pointer_array,
|
res= join->prepare(&sl->ref_pointer_array,
|
||||||
@ -308,6 +311,7 @@ int st_select_lex_unit::exec()
|
|||||||
}
|
}
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
records_at_start= table->file->records;
|
||||||
sl->join->exec();
|
sl->join->exec();
|
||||||
res= sl->join->error;
|
res= sl->join->error;
|
||||||
if (!res && union_result->flush())
|
if (!res && union_result->flush())
|
||||||
@ -321,8 +325,17 @@ int st_select_lex_unit::exec()
|
|||||||
thd->lex.current_select= lex_select_save;
|
thd->lex.current_select= lex_select_save;
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
if (found_rows_for_union && !sl->braces && sl->options & OPTION_FOUND_ROWS)
|
if (found_rows_for_union & sl->options)
|
||||||
add_rows+= (thd->limit_found_rows > rows) ? thd->limit_found_rows - rows : 0;
|
{
|
||||||
|
/*
|
||||||
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
optimized= 1;
|
optimized= 1;
|
||||||
@ -360,12 +373,8 @@ int st_select_lex_unit::exec()
|
|||||||
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
||||||
thd->options | SELECT_NO_UNLOCK,
|
thd->options | SELECT_NO_UNLOCK,
|
||||||
result, this, fake_select, 0);
|
result, this, fake_select, 0);
|
||||||
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 (!select_cursor->braces)
|
|
||||||
thd->limit_found_rows+= add_rows;
|
|
||||||
}
|
|
||||||
fake_select->exclude();
|
fake_select->exclude();
|
||||||
delete fake_select;
|
delete fake_select;
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user