Bug #27786 Inconsistent Operation Performing UNION On View With ORDER BY
Submitted: 12 Apr 2007 17:43 Modified: 24 Apr 2007 19:29
Reporter: Devin Withers
Status: Closed
Category:Server Severity:S3 (Non-critical)
Version:5.0.40-BK, 5.0.37 OS:Linux
Assigned to: Georgi Kodinov Target Version:
Tags: regression, Contribution

[12 Apr 2007 17:43] Devin Withers
Description:
Performing a UNION on two views when the views have ORDER BY clauses results in an
'Unknown column' error. Replacing even one of the views with an equivalent subselect, or
even a subselect which selects * from that view, does not result in an error. I'm not sure
which result is correct, but the fact that they are different is concerning. The error
started appearing after an upgrade from MySQL 5.0.18.

How to repeat:
CREATE TABLE test.thetable (a INT);
CREATE VIEW test.theview AS SELECT a FROM test.thetable ORDER BY a;
SELECT * FROM test.theview UNION SELECT * FROM test.theview; -- Results in: Unknown column
'test.thetable.a' in 'order clause'
SELECT * FROM (SELECT a FROM test.thetable ORDER BY a) a UNION SELECT * FROM (SELECT a
FROM test.thetable ORDER BY a) a; -- No Error
SELECT * FROM (SELECT * FROM test.theview) a UNION SELECT * FROM (SELECT * FROM
test.theview) a; -- No Error
(SELECT a FROM test.thetable ORDER BY a) UNION (SELECT a FROM test.thetable ORDER BY a);
-- No Error
[13 Apr 2007 9:53] Valeriy Kravchuk
Thank you for a bug report. Verified just as described with latest 5.0.40-BK on Linux.
[16 Apr 2007 2:26] Martin Friebe
possible patch and testcase

Attachment: union_view.patch (text/x-patch), 11.57 KiB.

[16 Apr 2007 2:34] Martin Friebe
A possible patch for the issue/ Explanation of the patch

The problem is, that if the last part of a union is not in braces, then global_parameters
will point to the last select_lex. (see sql_yacc.yy "selen_paren:" line 4277 and
"union_list:" line 9311 (mysql_new_select()))

This is correct and important to catch an order-by in cases like 
 select a from t1 union select b from t2 order by a;
so the order by is applied to the whole union.

However the order by of a view should not apply to the whole union. (It is private to the
view)

So when optimizing the view, I added checks for this.
If we are in a union, then a fake_select_lex has always been created
(mysql_new_select(move_down=false) ).
And it will always point to the last (not-braced) select-part of the union.

The other parts of a union (not last) are not affected, because global_param has moved to
the last part, by the time any view is unfolded.

The part to which global_param point will now take appropriate actions.
If it is not the last part, then there can be no additional order or limit. This is not
allowed by as it is not in braces.

Similiar for limits
[16 Apr 2007 12:45] Valeriy Kravchuk
Martin,

Thank you for a patch.
[16 Apr 2007 13:09] Martin Friebe
some more test cases. Italso works if the view is in braces and an order to the view is
given inside the braces

Attachment: union_view_tests.patch (text/x-patch), 2.10 KiB.

[20 Apr 2007 8:43] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/24970

ChangeSet@1.2457, 2007-04-20 09:42:52+03:00, gkodinov@magare.gmz +4 -0
  Bug #27786:
  When merging views into the enclosing statement
  the ORDER BY clause of the view is merged to the
  parent's ORDER BY clause.
  However when the VIEW is merged into an UNION
  branch the ORDER BY should be ignored. 
  Use of ORDER BY for individual SELECT statements
  implies nothing about the order in which the rows
  appear in the final result because UNION by default
  produces unordered set of rows.
  Fixed by ignoring the ORDER BY clause from the merge
  view when expanded in an UNION branch.
[20 Apr 2007 9:49] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/24971

ChangeSet@1.2457, 2007-04-20 10:49:45+03:00, gkodinov@magare.gmz +4 -0
  Bug #27786:
  When merging views into the enclosing statement
  the ORDER BY clause of the view is merged to the
  parent's ORDER BY clause.
  However when the VIEW is merged into an UNION
  branch the ORDER BY should be ignored. 
  Use of ORDER BY for individual SELECT statements
  implies nothing about the order in which the rows
  appear in the final result because UNION by default
  produces unordered set of rows.
  Fixed by ignoring the ORDER BY clause from the merge
  view when expanded in an UNION branch.
[21 Apr 2007 2:19] Martin Friebe
I am away, and have no means of testing, but reading the patch I was wondering.

the patch always ignores the order of the view, if merging with the union. How does that
work with

create view v1 select * from t1 order by a desc limit 2; 

If it woks, a testcase should be added.
[21 Apr 2007 17:19] Bugs System
Pushed into 5.1.18-beta
[21 Apr 2007 17:20] Bugs System
Pushed into 5.0.42
[24 Apr 2007 19:29] Paul DuBois
Noted in 5.0.42, 5.1.18 changelogs.

Performing a UNION on two views that had had ORDER BY clauses
resulted in an Unknown column error.