summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
authorunknown <igor@rurik.mysql.com>2006-04-20 22:15:38 -0700
committerunknown <igor@rurik.mysql.com>2006-04-20 22:15:38 -0700
commit9225a51c58def1fe505d0b46473b5294862309a7 (patch)
tree3e4a0a6b006e1b415ec3f8cac40152485b84e281 /sql/sql_yacc.yy
parentd7055274edf92e9d1e02caa1c1f567c20cfc5463 (diff)
downloadmariadb-git-9225a51c58def1fe505d0b46473b5294862309a7.tar.gz
Fixed bug #18767.
The bug caused wrong result sets for union constructs of the form (SELECT ... ORDER BY order_list1 [LIMIT n]) ORDER BY order_list2. For such queries order lists were concatenated and limit clause was completely neglected. mysql-test/r/order_by.result: Added a test case for bug #18767. mysql-test/t/order_by.test: Added a test case for bug #18767. sql/sql_lex.h: Fixed bug #18767. Placed the code the created a fake SELECT_LEX into a separate function. sql/sql_parse.cc: Fixed bug #18767. Placed the code the created a fake SELECT_LEX into a separate function. sql/sql_select.cc: Fixed bug #18767. Changed the condition on which a SELECT is treated as part of a UNION. The SELECT in (SELECT ... ORDER BY order_list1 [LIMIT n]) ORDER BY order_list2 now is handled in the same way as the first SELECT in a UNION sequence. sql/sql_union.cc: Fixed bug #18767. Changed the condition at which a SELECT is treated as part of a UNION. The SELECT in (SELECT ... ORDER BY order_list1 [LIMIT n]) ORDER BY order_list2 now is handled in the same way as the first SELECT in a UNION sequence. sql/sql_yacc.yy: Fixed bug #18767. Changed the condition at which a SELECT is treated as part of a UNION. The SELECT in (SELECT ... ORDER BY order_list1 [LIMIT n]) ORDER BY order_list2 now is handled in the same way as the first SELECT in a UNION sequence. In the same way is handled the SELECT in (SELECT ... LIMIT n) ORDER BY order list. Yet if there is neither ORDER BY nor LIMIT in the single-select union construct (SELECT ...) ORDER BY order_list then it is still handled as simple select with an order clause.
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy24
1 files changed, 21 insertions, 3 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 05d95b57abb..162b4183c84 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -3790,15 +3790,33 @@ order_clause:
ORDER_SYM BY
{
LEX *lex=Lex;
- if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE &&
- lex->current_select->olap !=
- UNSPECIFIED_OLAP_TYPE)
+ SELECT_LEX *sel= lex->current_select;
+ SELECT_LEX_UNIT *unit= sel-> master_unit();
+ if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
+ sel->olap != UNSPECIFIED_OLAP_TYPE)
{
net_printf(lex->thd, ER_WRONG_USAGE,
"CUBE/ROLLUP",
"ORDER BY");
YYABORT;
}
+ if (lex->sql_command != SQLCOM_ALTER_TABLE && !unit->fake_select_lex)
+ {
+ /*
+ A query of the of the form (SELECT ...) ORDER BY order_list is
+ executed in the same way as the query
+ SELECT ... ORDER BY order_list
+ unless the SELECT construct contains ORDER BY or LIMIT clauses.
+ Otherwise we create a fake SELECT_LEX if it has not been created
+ yet.
+ */
+ SELECT_LEX *first_sl= unit->first_select();
+ if (!first_sl->next_select() &&
+ (first_sl->order_list.elements ||
+ first_sl->select_limit != HA_POS_ERROR) &&
+ unit->add_fake_select_lex(lex->thd))
+ YYABORT;
+ }
} order_list;
order_list: