diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 71d743f37b9..70dd6b2550f 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3319,4 +3319,39 @@ lgid clid 2 YES DROP VIEW v1; DROP table t1,t2; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +CREATE VIEW v1 AS SELECT a FROM t1 ORDER BY a; +SELECT * FROM t1 UNION SELECT * FROM v1; +a +1 +2 +3 +EXPLAIN SELECT * FROM t1 UNION SELECT * FROM v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 +2 UNION t1 ALL NULL NULL NULL NULL 3 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +SELECT * FROM v1 UNION SELECT * FROM t1; +a +1 +2 +3 +EXPLAIN SELECT * FROM v1 UNION SELECT * FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 +2 UNION t1 ALL NULL NULL NULL NULL 3 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +SELECT * FROM t1 UNION SELECT * FROM v1 ORDER BY a; +a +1 +2 +3 +EXPLAIN SELECT * FROM t1 UNION SELECT * FROM v1 ORDER BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 +2 UNION t1 ALL NULL NULL NULL NULL 3 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL Using filesort +DROP VIEW v1; +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 920fcee3b24..e5bf9de13eb 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3205,4 +3205,20 @@ SELECT * FROM v1; DROP VIEW v1; DROP table t1,t2; +# +# Bug#27786: Inconsistent Operation Performing UNION On View With ORDER BY +# +CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2),(3); +CREATE VIEW v1 AS SELECT a FROM t1 ORDER BY a; + +SELECT * FROM t1 UNION SELECT * FROM v1; +EXPLAIN SELECT * FROM t1 UNION SELECT * FROM v1; +SELECT * FROM v1 UNION SELECT * FROM t1; +EXPLAIN SELECT * FROM v1 UNION SELECT * FROM t1; +SELECT * FROM t1 UNION SELECT * FROM v1 ORDER BY a; +EXPLAIN SELECT * FROM t1 UNION SELECT * FROM v1 ORDER BY a; + +DROP VIEW v1; +DROP TABLE t1; + --echo End of 5.0 tests. diff --git a/sql/sql_lex.h b/sql/sql_lex.h index de7de0d46e9..2ff29d684d1 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -468,6 +468,7 @@ public: bool change_result(select_subselect *result, select_subselect *old_result); void set_limit(st_select_lex *values); void set_thd(THD *thd_arg) { thd= thd_arg; } + inline bool is_union (); friend void lex_start(THD *thd, uchar *buf, uint length); friend int subselect_union_engine::exec(); @@ -700,6 +701,13 @@ public: }; typedef class st_select_lex SELECT_LEX; + +inline bool st_select_lex_unit::is_union () +{ + return first_select()->next_select() && + first_select()->next_select()->linkage == UNION_TYPE; +} + #define ALTER_ADD_COLUMN 1 #define ALTER_DROP_COLUMN 2 #define ALTER_CHANGE_COLUMN 4 diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 83beec3d1be..95dec40450f 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1263,13 +1263,18 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, unit->slave= save_slave; // fix include_down initialisation } + /* + We can safely ignore the VIEW's ORDER BY if we merge into union + branch, as order is not important there. + */ + if (!table->select_lex->master_unit()->is_union()) + table->select_lex->order_list.push_back(&lex->select_lex.order_list); /* This SELECT_LEX will be linked in global SELECT_LEX list to make it processed by mysql_handle_derived(), but it will not be included to SELECT_LEX tree, because it will not be executed - */ - table->select_lex->order_list.push_back(&lex->select_lex.order_list); + */ goto ok; }