summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <Sinisa@sinisa.nasamreza.org>2003-08-20 13:56:32 +0300
committerunknown <Sinisa@sinisa.nasamreza.org>2003-08-20 13:56:32 +0300
commit7a417ae37b4bcd87b863644b29f15df56aadfd2d (patch)
tree90e4e736ab27a132cfdde4f838ebbd12cda2ed62 /sql
parentad7055507ab17aa188f6f0d5e101e6ae210269e5 (diff)
downloadmariadb-git-7a417ae37b4bcd87b863644b29f15df56aadfd2d.tar.gz
fixing limit and SQL_CALC_FOUND_ROWS issues
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_union.cc40
1 files changed, 24 insertions, 16 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 6c3c5350966..cfed5083b71 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -123,7 +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= 0;
+ 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;
@@ -131,13 +131,6 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
bzero((char *)&tmp_table_param,sizeof(TMP_TABLE_PARAM));
thd->lex.current_select= select_cursor= first_select_in_union();
/* Global option */
- if (((void*)(global_parameters)) == ((void*)this))
- {
- found_rows_for_union= first_select()->options & OPTION_FOUND_ROWS &&
- global_parameters->select_limit;
- if (found_rows_for_union)
- first_select()->options&= ~OPTION_FOUND_ROWS;
- }
if (t_and_f)
{
// Item list and tables will be initialized by mysql_derived
@@ -256,6 +249,7 @@ int st_select_lex_unit::exec()
{
SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
SELECT_LEX *select_cursor=first_select_in_union();
+ unsigned int add_rows=0;
DBUG_ENTER("st_select_lex_unit::exec");
if (executed && !(dependent || uncacheable))
@@ -272,6 +266,7 @@ int st_select_lex_unit::exec()
}
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
{
+ unsigned int rows;
if (optimized)
res= sl->join->reinit();
else
@@ -286,6 +281,11 @@ int st_select_lex_unit::exec()
select_limit_cnt= HA_POS_ERROR; // no limit
if (select_limit_cnt == HA_POS_ERROR)
sl->options&= ~OPTION_FOUND_ROWS;
+ else if (found_rows_for_union)
+ {
+ rows= thd->select_limit;
+ sl->options|= OPTION_FOUND_ROWS;
+ }
res= join->prepare(&sl->ref_pointer_array,
(TABLE_LIST*) sl->table_list.first, sl->with_wild,
@@ -321,6 +321,8 @@ int st_select_lex_unit::exec()
thd->lex.current_select= lex_select_save;
DBUG_RETURN(res);
}
+ 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;
}
}
optimized= 1;
@@ -337,15 +339,17 @@ int st_select_lex_unit::exec()
if (!thd->is_fatal_error) // Check if EOM
{
SELECT_LEX *fake_select = new SELECT_LEX(&thd->lex);
- offset_limit_cnt= (select_cursor->braces ?
- global_parameters->offset_limit : 0);
- select_limit_cnt= (select_cursor->braces ?
- global_parameters->select_limit+
- global_parameters->offset_limit : HA_POS_ERROR);
- if (select_limit_cnt < global_parameters->select_limit)
- select_limit_cnt= HA_POS_ERROR; // no limit
+ if (select_cursor->braces)
+ {
+ offset_limit_cnt= global_parameters->offset_limit;
+ select_limit_cnt= global_parameters->select_limit + global_parameters->offset_limit;
+ if (select_limit_cnt < global_parameters->select_limit)
+ select_limit_cnt= HA_POS_ERROR; // no limit
+ }
if (select_limit_cnt == HA_POS_ERROR)
thd->options&= ~OPTION_FOUND_ROWS;
+ else if (found_rows_for_union && !describe)
+ thd->options|= OPTION_FOUND_ROWS;
fake_select->ftfunc_list= &empty_list;
fake_select->table_list.link_in_list((byte *)&result_table_list,
(byte **)&result_table_list.next);
@@ -357,7 +361,11 @@ int st_select_lex_unit::exec()
thd->options | SELECT_NO_UNLOCK,
result, this, fake_select, 0);
if (found_rows_for_union && !res)
- thd->limit_found_rows = (ulonglong)table->file->records;
+ {
+ thd->limit_found_rows= table->file->records;
+ if (!select_cursor->braces)
+ thd->limit_found_rows+= add_rows;
+ }
fake_select->exclude();
delete fake_select;
/*