|
Thanks Geoff and Knut, these scripts are great. Perhaps the common element
is that in all these scripts, the "extra" column is in both the WHERE and ORDER BY clauses? Are you able to provide a target release for a fix? It would be a big help to know when a fix will come in as this bug causes a problem for me in a production environment.
I think I've found the cause of the problem. This code in SelectNode.preprocess() will be executed when all the columns in the ORDER BY clause are known to have constant values because of the WHERE clause:
/* ** It's possible for the order by list to shrink to nothing ** as a result of removing constant columns. If this happens, ** get rid of the list entirely. */ if (orderByList.size() == 0) { orderByList = null; } Later, in SelectNode.genProjectRestrict() the extra ORDER BY columns are supposed to be removed from the result, but this is only done if orderByList != null, as it assumes that (orderByList == null) means that there are no columns to remove. Calling resultColumns.removeOrderByColumns() when we set orderByList to null appears to fix the problem, but I haven't run the regression tests yet.
Knut Anders Hatlen made changes - 29/Dec/08 08:06 PM
Thanks Knut for having a go at this. Your analysis sounds quite good to me.
One interesting variant will be when the select list contains *, as I think there are some complexities about whether you can remove the ORDER BY column in this case, since it should end up in the result after all. So it might be worth ensuring that you try a few test cases including select * queries when testing the patch.
Knut Anders Hatlen made changes - 30/Dec/08 08:45 AM
Here's a patch with a fix and a test case. Both suites.All and derbyall ran cleanly.
Thanks for the suggestion about * in the select list, Bryan. I tested that manually, and I didn't find any problem. ResultColumnList.removeOrderByColumns() should only remove columns that have been added for the order by, and it should leave the original select list intact. I haven't added any test case to ensure that elimination of the order by clause doesn't remove columns that should have been in the result, as that seems to be tested already.
Knut Anders Hatlen made changes - 30/Dec/08 09:05 AM
Knut Anders Hatlen made changes - 30/Dec/08 09:05 AM
Hi Knut, the patch looks fine to me. I verified that the new test fails
without the change to SelectNode.java and passes with the change. I also tried a few other test cases, and confirmed that their results look reasonable. I'm not sure that they add anything all that valuable to the patch, but for completeness here's the new cases I tried: 1) selecting an actual column from the table rather than a constant expression 2) selecting * from the table 3) selecting from the table with a WHERE clause that does NOT reduce the ORDER BY to a a constant. If you think they're useful enough to add to the patch, go for it, otherwise I think you can just commit the patch as is. Thanks again for picking this issue up! ij> create table d3997_a(a int, b int, c int); 0 rows inserted/updated/deleted ij> insert into d3997_a values (1,2,3); 1 row inserted/updated/deleted ij> select a from d3997_a where b = 2 order by b; A ----------- 1 1 row selected ij> select * from d3997_a where b != 2 order by b; A |B |C ----------------------------------- 0 rows selected ij> select c from d3997_a where b > 1 order by b; C ----------- 3 1 row selected
Thanks for looking at the patch, Bryan, and for the extra test cases.
I added some variations of your test cases and a test case for dynamic columns (see below) and committed revision 730188. I plan to back-port the fix to 10.4 so I'm leaving the issue open. -- -- to order by were known to be constant, made extra columns appear in -- the result. create table d3997(x int, y int, z int); -- These queries used to have two result columns, but should only have one select 1 from d3997 where x=1 order by x; select y from d3997 where x=1 order by x; -- Used to have three columns, should only have two select y,z from d3997 where x=1 order by x; -- Used to have three columns, should only have one select x from d3997 where y=1 and z=1 order by y,z; -- Dynamic parameters are also constants (expect one column) execute 'select x from d3997 where y=? order by y' using 'values 1'; -- Order by columns should not be removed from the result here select * from d3997 where x=1 order by x; select x,y,z from d3997 where x=1 order by x; select x,y,z from d3997 where x=1 and y=1 order by x,y; -- Order by should not be eliminated here (not constant values). Insert some -- data in reverse order to verify that the results are sorted. insert into d3997 values (9,8,7),(6,5,4),(3,2,1); select * from d3997 where y<>2 order by y; select z from d3997 where y>2 order by y; drop table d3997;
Knut Anders Hatlen made changes - 30/Dec/08 05:22 PM
Thanks guys. Do we know when a derby binary release will include this fix?
There has been some talk about producing a 10.5 release in the first quarter of 2009, but no target date has been decided yet.
http://mail-archives.apache.org/mod_mbox/db-derby-dev/200811.mbox/%3C491C864E.6010008@sun.com%3E
Merged the fix to 10.4 and committed revision 731599.
Knut Anders Hatlen made changes - 05/Jan/09 03:32 PM
Rick Hillegas made changes - 09/Feb/09 02:13 PM
Rick Hillegas made changes - 09/Feb/09 06:27 PM
Myrna van Lunteren made changes - 04/May/09 06:22 PM
This exists back to 10.1, fixing affects version
Kathey Marsden made changes - 18/Jun/09 06:08 PM
Kathey Marsden made changes - 18/Jun/09 06:10 PM
I am backporting this patch to 10.2 and notice that it uses ResultColumnList.removeOderByColumns which was added in
checked into 10.3. This will still go to 10.2 and 10.1
Kathey Marsden made changes - 22/Jun/09 07:15 PM
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ij> create table t (x int primary key, y int);
0 rows inserted/updated/deleted
ij> select y from t where x = 1 order by x;
Y |X
-----------------------
0 rows selected
Remove the WHERE clause or the ORDER BY clause, and the column X disappears.