diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 33fc4333d1c..7f0ec2275d7 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1644,3 +1644,103 @@ b 2 DROP TABLE t1,t2; End of 5.1 tests +# +# Bug#57986 ORDER BY clause is not used after a UNION, +# if embedded in a SELECT +# +CREATE TABLE t1 (c1 VARCHAR(10) NOT NULL, c2 INT NOT NULL); +CREATE TABLE t2 (c1 VARCHAR(10) NOT NULL, c2 INT NOT NULL); +INSERT INTO t1 (c1, c2) VALUES ('t1a', 1), ('t1a', 2), ('t1a', 3), ('t1b', 2), ('t1b', 1); +INSERT INTO t2 (c1, c2) VALUES ('t2a', 1), ('t2a', 2), ('t2a', 3), ('t2b', 2), ('t2b', 1); +SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY c2, c1; +c1 c2 +t1a 1 +t1b 1 +t2a 1 +t2b 1 +t1a 2 +t1b 2 +t2a 2 +t2b 2 +t1a 3 +t2a 3 +SELECT * FROM t1 UNION (SELECT * FROM t2) ORDER BY c2, c1; +c1 c2 +t1a 1 +t1b 1 +t2a 1 +t2b 1 +t1a 2 +t1b 2 +t2a 2 +t2b 2 +t1a 3 +t2a 3 +SELECT * FROM t1 UNION (SELECT * FROM t2 ORDER BY c2, c1); +c1 c2 +t1a 1 +t1a 2 +t1a 3 +t1b 2 +t1b 1 +t2a 1 +t2a 2 +t2a 3 +t2b 2 +t2b 1 +SELECT c1, c2 FROM ( +SELECT c1, c2 FROM t1 +UNION +(SELECT c1, c2 FROM t2) +ORDER BY c2, c1 +) AS res; +c1 c2 +t1a 1 +t1b 1 +t2a 1 +t2b 1 +t1a 2 +t1b 2 +t2a 2 +t2b 2 +t1a 3 +t2a 3 +SELECT c1, c2 FROM ( +SELECT c1, c2 FROM t1 +UNION +(SELECT c1, c2 FROM t2) +ORDER BY c2 DESC, c1 LIMIT 1 +) AS res; +c1 c2 +t1a 3 +SELECT c1, c2 FROM ( +SELECT c1, c2 FROM t1 +UNION +(SELECT c1, c2 FROM t2 ORDER BY c2 DESC, c1 LIMIT 1) +) AS res; +c1 c2 +t1a 1 +t1a 2 +t1a 3 +t1b 2 +t1b 1 +t2a 3 +SELECT c1, c2 FROM ( +SELECT c1, c2 FROM t1 +UNION +SELECT c1, c2 FROM t2 +ORDER BY c2 DESC, c1 DESC LIMIT 1 +) AS res; +c1 c2 +t2a 3 +SELECT c1, c2 FROM ( +( +(SELECT c1, c2 FROM t1) +UNION +(SELECT c1, c2 FROM t2) +) +ORDER BY c2 DESC, c1 ASC LIMIT 1 +) AS res; +c1 c2 +t1a 3 +DROP TABLE t1, t2; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 596fc5f41ef..694f1bab15c 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1117,3 +1117,57 @@ DROP TABLE t1,t2; --echo End of 5.1 tests + +--echo # +--echo # Bug#57986 ORDER BY clause is not used after a UNION, +--echo # if embedded in a SELECT +--echo # + +CREATE TABLE t1 (c1 VARCHAR(10) NOT NULL, c2 INT NOT NULL); +CREATE TABLE t2 (c1 VARCHAR(10) NOT NULL, c2 INT NOT NULL); + + +INSERT INTO t1 (c1, c2) VALUES ('t1a', 1), ('t1a', 2), ('t1a', 3), ('t1b', 2), ('t1b', 1); +INSERT INTO t2 (c1, c2) VALUES ('t2a', 1), ('t2a', 2), ('t2a', 3), ('t2b', 2), ('t2b', 1); + +SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY c2, c1; +SELECT * FROM t1 UNION (SELECT * FROM t2) ORDER BY c2, c1; +SELECT * FROM t1 UNION (SELECT * FROM t2 ORDER BY c2, c1); + +SELECT c1, c2 FROM ( + SELECT c1, c2 FROM t1 + UNION + (SELECT c1, c2 FROM t2) + ORDER BY c2, c1 +) AS res; + +SELECT c1, c2 FROM ( + SELECT c1, c2 FROM t1 + UNION + (SELECT c1, c2 FROM t2) + ORDER BY c2 DESC, c1 LIMIT 1 +) AS res; + +SELECT c1, c2 FROM ( + SELECT c1, c2 FROM t1 + UNION + (SELECT c1, c2 FROM t2 ORDER BY c2 DESC, c1 LIMIT 1) +) AS res; + +SELECT c1, c2 FROM ( + SELECT c1, c2 FROM t1 + UNION + SELECT c1, c2 FROM t2 + ORDER BY c2 DESC, c1 DESC LIMIT 1 +) AS res; + +SELECT c1, c2 FROM ( + ( + (SELECT c1, c2 FROM t1) + UNION + (SELECT c1, c2 FROM t2) + ) + ORDER BY c2 DESC, c1 ASC LIMIT 1 +) AS res; + +DROP TABLE t1, t2; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9aa938437b1..c283747156a 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -9396,7 +9396,7 @@ table_factor: ; select_derived_union: - select_derived opt_order_clause opt_limit_clause + select_derived opt_union_order_or_limit | select_derived_union UNION_SYM union_option @@ -9412,7 +9412,7 @@ select_derived_union: */ Lex->pop_context(); } - opt_order_clause opt_limit_clause + opt_union_order_or_limit ; /* The equivalent of select_init2 for nested queries. */ @@ -13862,6 +13862,11 @@ union_opt: | union_order_or_limit { $$= 1; } ; +opt_union_order_or_limit: + /* Empty */ + | union_order_or_limit + ; + union_order_or_limit: { THD *thd= YYTHD;