summaryrefslogtreecommitdiff
path: root/sql/sql_union.cc
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2004-10-22 22:51:16 +0400
committerunknown <konstantin@mysql.com>2004-10-22 22:51:16 +0400
commit9b5cf9464c18c250f45e89a5291676571487cfe5 (patch)
tree9ddb77acd9ee81b116c0132fcd2d00fd6dc1342f /sql/sql_union.cc
parent1cd249e0edb9aeeb46686ef548a4901c5a5340b2 (diff)
downloadmariadb-git-9b5cf9464c18c250f45e89a5291676571487cfe5.tar.gz
A fix and test case for Bug#6088 "FOUND_ROWS returns wrong values for
prepared statements when LIMIT is used" and post-review comments. The fix changes the approach we calculate the need for ORDER BY in UNION: the previous was not PS friendly, as it damaged SELECT_LEX options in case of single select. mysql-test/r/ps.result: Test results fixed: the test case for Bug#6088 mysql-test/r/subselect.result: Test results fixed: now we don't perform ORDER BY for parts of UNION if there is no LIMIT clause. mysql-test/t/ps.test: A test case for Bug#6088 "FOUND_ROWS returns wrong values for prepared statements when LIMIT is used". sql/sql_union.cc: The actual fix for Bug#6088: - don't modify SELECT_LEX'es - use boolean variable can_skip_order_by to check if we can skip ORDER BY in UNION
Diffstat (limited to 'sql/sql_union.cc')
-rw-r--r--sql/sql_union.cc28
1 files changed, 13 insertions, 15 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 44004e1238d..f9a1908355b 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -147,6 +147,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
SELECT_LEX *sl, *first_select;
select_result *tmp_result;
+ bool is_union;
DBUG_ENTER("st_select_lex_unit::prepare");
describe= test(additional_options & SELECT_DESCRIBE);
@@ -183,10 +184,11 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
thd_arg->lex->current_select= sl= first_select= first_select_in_union();
found_rows_for_union= first_select->options & OPTION_FOUND_ROWS;
+ is_union= test(first_select->next_select());
/* Global option */
- if (first_select->next_select())
+ if (is_union)
{
if (!(tmp_result= union_result= new select_union(0)))
goto err;
@@ -195,14 +197,11 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
tmp_result= sel_result;
}
else
- {
tmp_result= sel_result;
- // single select should be processed like select in p[arantses
- first_select->braces= 1;
- }
for (;sl; sl= sl->next_select())
{
+ bool can_skip_order_by;
sl->options|= SELECT_NO_UNLOCK;
JOIN *join= new JOIN(thd_arg, sl->item_list,
sl->options | thd_arg->options | additional_options,
@@ -217,14 +216,17 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
select_limit_cnt= HA_POS_ERROR; // no limit
if (select_limit_cnt == HA_POS_ERROR || sl->braces)
sl->options&= ~OPTION_FOUND_ROWS;
-
+
+ can_skip_order_by= is_union &&
+ (!sl->braces || select_limit_cnt == HA_POS_ERROR);
+
res= join->prepare(&sl->ref_pointer_array,
(TABLE_LIST*) sl->table_list.first, sl->with_wild,
sl->where,
- ((sl->braces) ? sl->order_list.elements : 0) +
- sl->group_list.elements,
- (sl->braces) ?
- (ORDER *)sl->order_list.first : (ORDER *) 0,
+ (can_skip_order_by ? 0 : sl->order_list.elements) +
+ sl->group_list.elements,
+ can_skip_order_by ?
+ (ORDER*) 0 : (ORDER *)sl->order_list.first,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
@@ -264,10 +266,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
}
}
- if (first_select->next_select())
+ if (is_union)
{
- /* This is not a single select */
-
/*
Check that it was possible to aggregate
all collations together for UNION.
@@ -364,8 +364,6 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
}
}
}
- else
- first_select->braces= 0; // remove our changes
thd_arg->lex->current_select= lex_select_save;