diff options
author | unknown <konstantin@mysql.com> | 2004-10-22 22:51:16 +0400 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2004-10-22 22:51:16 +0400 |
commit | 9b5cf9464c18c250f45e89a5291676571487cfe5 (patch) | |
tree | 9ddb77acd9ee81b116c0132fcd2d00fd6dc1342f /sql/sql_union.cc | |
parent | 1cd249e0edb9aeeb46686ef548a4901c5a5340b2 (diff) | |
download | mariadb-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.cc | 28 |
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; |