Bug #28011 | UNION returns wrong result, if order by must not be removed | ||
---|---|---|---|
Submitted: | 22 Apr 2007 6:57 | Modified: | 11 Jul 2007 17:42 |
Reporter: | Martin Friebe (Gold Quality Contributor) (OCA) | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server | Severity: | S3 (Non-critical) |
Version: | 5.0.44-BK, 5.0.42bk | OS: | Any |
Assigned to: | Evgeny Potemkin | CPU Architecture: | Any |
Tags: | functions, order by, qc, UNION, variables, VIEW |
[22 Apr 2007 6:57]
Martin Friebe
[22 Apr 2007 7:09]
Martin Friebe
just seen I copied and pasted to much. the view in the 2nd example is invalid. the 2nd part of how to repaet should only be: -------- drop table if exists t1; create table t1 (a int); insert into t1 values (10), (20), (20), (30); set @a=null; select a-@a, @a, @a:=a from t1 order by a desc; set @a=null; (select a-@a, @a, @a:=a from t1 order by a desc) UNION (select 9,9,9); The view is only broken in the first part, with the function.
[14 Jun 2007 15:03]
Valeriy Kravchuk
Verified just as described with latest 5.0.44-BK on Linux. In particular: openxs@suse:~/dbs/5.0> bin/mysql -uroot test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.0.44-debug Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> drop view if exists v1; Query OK, 0 rows affected (0.00 sec) mysql> drop table if exists t1; Query OK, 0 rows affected (0.05 sec) mysql> drop function if exists prv; Query OK, 0 rows affected, 1 warning (0.05 sec) mysql> set GLOBAL log_bin_trust_function_creators=1; Query OK, 0 rows affected (0.00 sec) mysql> delimiter | mysql> create function prv (v int) returns int -> begin -> declare p int; -> set p =@a; -> set @a =v; -> return p; -> end| Query OK, 0 rows affected (0.02 sec) mysql> delimiter ; mysql> mysql> create table t1 (a int); Query OK, 0 rows affected (0.01 sec) mysql> insert into t1 values (10), (20), (20), (30); Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> set @a = null; select a, prv(a) from t1 order by a; Query OK, 0 rows affected (0.00 sec) +------+--------+ | a | prv(a) | +------+--------+ | 10 | NULL | | 20 | 10 | | 20 | 20 | | 30 | 20 | +------+--------+ 4 rows in set (0.02 sec) @amysql> set @a = null; select a, prv(a) from t1 order by a desc; Query OK, 0 rows affected (0.00 sec) +------+--------+ | a | prv(a) | +------+--------+ | 30 | NULL | | 20 | 30 | | 20 | 20 | | 10 | 20 | +------+--------+ 4 rows in set (0.00 sec) mysql> create ALGORITHM=MERGE view v1 as select a, prv(a) from t1 order by a desc; Query OK, 0 rows affected (0.01 sec) mysql> set @a= null; select * from v1; Query OK, 0 rows affected (0.01 sec) +------+--------+ | a | prv(a) | +------+--------+ | 30 | NULL | | 20 | 30 | | 20 | 20 | | 10 | 20 | +------+--------+ 4 rows in set (0.00 sec) mysql> mysql> set @a = null; select * from v1 UNION select 0,0; Query OK, 0 rows affected (0.00 sec) +------+--------+ | a | prv(a) | +------+--------+ | 10 | NULL | | 20 | 10 | | 20 | 20 | | 30 | 20 | | 0 | 0 | +------+--------+ 5 rows in set (0.01 sec) mysql> set @a = null; select 0,0 UNION select * from v1; Query OK, 0 rows affected (0.00 sec) +------+------+ | 0 | 0 | +------+------+ | 0 | 0 | | 10 | NULL | | 20 | 10 | | 20 | 20 | | 30 | 20 | +------+------+ 5 rows in set (0.00 sec) mysql> set @a = null; (select 0,0) UNION (select * from v1); Query OK, 0 rows affected (0.00 sec) +------+------+ | 0 | 0 | +------+------+ | 0 | 0 | | 10 | NULL | | 20 | 10 | | 20 | 20 | | 30 | 20 | +------+------+ 5 rows in set (0.00 sec)
[25 Jun 2007 19:47]
Evgeny Potemkin
This is not a bug. The manual says that the ORDER BY clause will be optimized away in UNION unless the LIMIT clause is present. http://dev.mysql.com/doc/refman/5.0/en/union.html This is exactly what happens here. When a view is merged its ORDER BY clause is appended to the embedding select. So this rule is applicable here. To prevent dropping of the ORDER BY clause you can recreate view with the ALGORITHM=TEMPTABLE option. Changing a user variable in a select is a side effect and the side effects are implementation dependent. Consistent handling of them isn't guaranteed.