History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: COR-1062
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Patrick Roemer
Reporter: Luciano Di Cocco
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
db4o Core

Sort result incorrect after OR

Created: 31/Dec/07 01:37 PM   Updated: 14/Oct/09 01:53 PM
Component/s: None
Affects Version/s: None
Fix Version/s: 7.11.115

Time Tracking:
Original Estimate: Not Specified
Remaining Estimate: 0h
Time Spent - 1.5h
Time Spent: 1.5h
Time Spent - 1.5h

Issue Links:
Related
 
Resulted
 

Order: 3
Iteration: 117
Resolution Date: 14/Oct/09 12:35 PM
First Response Date: 10/Feb/09 01:44 PM
Labels:
Participants: Carl Rosenberger, Luciano Di Cocco and Patrick Roemer
Number of Attachments: 0
Number of Comments: 3


 Description  « Hide
I think there is some bug in the current implementation of OR filtering in SODA if the same fields are used in sorting. I found the bahaviour in 6.1, 6.4 and now in 7.0. Or iy could be that I'm doing it in a way that I think it's right but it isn't.
At least in my case, it seems that sorting is done BEFORE applying the OR clause. In my demo code for LINQ to db4o (at the moment is Test004) I translate the following query:
            var q =
                from p in db.Products
                where p.UnitPrice > 10m || p.Discontinued == true
                orderby p.UnitPrice
                select new { p.UnitPrice, p.Discontinued };

The SODA translation is IQuery query = ObjectContainer.Query(); query.Constrain(typeof(Ldc.Db4o.Northwind.Product));
SODAHelper.Or(
        new IConstraint[] {
                query.Descend("_UnitPrice").Constrain(10).Greater(),
                query.Descend("_Discontinued").Constrain(True),
                }
        );
query.Descend("_UnitPrice").OrderAscending();

The SODAHelper.Or is just an helper function to easily construct an OR clause. It is simply
        public static IConstraint Or(IConstraint[] constraints)
        {
            IConstraint constraint1 = constraints[0];
            for (int i = 1; i < constraints.Length; i++)
            {
                constraint1 = constraint1.Or(constraints[i]);
            }
            return constraint1;
        }
The result is:
UnitPrice=12,0000 Discontinued=False
UnitPrice=12,5000 Discontinued=False
UnitPrice=12,5000 Discontinued=False
UnitPrice=12,7500 Discontinued=False
UnitPrice=13,0000 Discontinued=False
UnitPrice=13,2500 Discontinued=False
UnitPrice=14,0000 Discontinued=False
UnitPrice=14,0000 Discontinued=True
UnitPrice=14,0000 Discontinued=False
UnitPrice=14,0000 Discontinued=False
UnitPrice=15,0000 Discontinued=False
UnitPrice=15,0000 Discontinued=False
UnitPrice=15,5000 Discontinued=False
UnitPrice=16,2500 Discontinued=False
UnitPrice=17,0000 Discontinued=False
UnitPrice=17,4500 Discontinued=False
UnitPrice=18,0000 Discontinued=False
UnitPrice=18,0000 Discontinued=False
UnitPrice=18,0000 Discontinued=False
UnitPrice=18,4000 Discontinued=False
UnitPrice=19,0000 Discontinued=False
UnitPrice=19,0000 Discontinued=False
UnitPrice=19,4500 Discontinued=False
UnitPrice=19,5000 Discontinued=False
UnitPrice=20,0000 Discontinued=False
UnitPrice=21,0000 Discontinued=False
UnitPrice=21,0000 Discontinued=False
UnitPrice=21,0500 Discontinued=False
UnitPrice=21,3500 Discontinued=True
UnitPrice=21,5000 Discontinued=False
UnitPrice=22,0000 Discontinued=False
UnitPrice=23,2500 Discontinued=False
UnitPrice=24,0000 Discontinued=False
UnitPrice=25,0000 Discontinued=False
UnitPrice=25,8900 Discontinued=False
UnitPrice=26,0000 Discontinued=False
UnitPrice=28,5000 Discontinued=False
UnitPrice=30,0000 Discontinued=False
UnitPrice=31,0000 Discontinued=False
UnitPrice=31,2300 Discontinued=False
UnitPrice=32,0000 Discontinued=False
UnitPrice=32,8000 Discontinued=True
UnitPrice=33,2500 Discontinued=False
UnitPrice=34,0000 Discontinued=False
UnitPrice=34,8000 Discontinued=False
UnitPrice=36,0000 Discontinued=False
UnitPrice=38,0000 Discontinued=False
UnitPrice=38,0000 Discontinued=False
UnitPrice=39,0000 Discontinued=True
UnitPrice=40,0000 Discontinued=False
UnitPrice=43,9000 Discontinued=False
UnitPrice=43,9000 Discontinued=False
UnitPrice=45,6000 Discontinued=True
UnitPrice=46,0000 Discontinued=False
UnitPrice=49,3000 Discontinued=False
UnitPrice=53,0000 Discontinued=False
UnitPrice=55,0000 Discontinued=False
UnitPrice=62,5000 Discontinued=False
UnitPrice=81,0000 Discontinued=False
UnitPrice=97,0000 Discontinued=True
UnitPrice=123,7900 Discontinued=True
UnitPrice=263,5000 Discontinued=False
UnitPrice=777,7700 Discontinued=False
UnitPrice=4,5000 Discontinued=True

The last result, the only one where the right side of the OR clause apply, should be the first. My guess is that SODA code first apply the sort and then chain the results, while it should do the opposite.


 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Carl Rosenberger - 10/Feb/09 01:44 PM
Reproducible on the Java side with OrderedOrConstraintTestCase

Patrick Roemer - 03/Mar/09 12:41 PM
This is not only a problem of execution order. With a constraint on the query node used for ordering, only candidates accepted by this constraint will take part in the ordering process. To fix this, the ordering will have to be "pushed" up to the query root instead (or candidates will have to be pushed down from there for sorting).

Patrick Roemer - 14/Oct/09 12:35 PM
Fixed as a byproduct of COR-1775.