Community
Participate
Working Groups
Build Identifier: 2.1.0 In memory query (ReadAllQuery.conformResultsInUnitOfWork) with selection criteria consisting of BigDecimal attribute equality comparation fails if compared values has different BigDecimal.scale. Bad result of Expression.equal expression evaluation comes from BigDecimal.equal method usage. This method is not suited for numerical value comparation as javadoc imply. It is true for Double.equals as well. Solution: Replace "if (this.selector == Equal) {...} else if (this.selector == NotEqual) {...}" code block in method ExpressionOperator.doesRelationConform with this: <code> if (this.selector == Equal || this.selector == NotEqual) { if ((left == null) && (right == null)) { return this.selector == Equal; } else if ((left == null) || (right == null)) { return this.selector == NotEqual; } if (left instanceof Number && left instanceof Comparable && right instanceof Comparable && left.getClass().equals (right.getClass())) { return (((Comparable) left).compareTo( (Comparable) right) == 0) == (this.selector == Equal); } if (((left instanceof Number) && (right instanceof Number)) && (left.getClass() != right.getClass())) { return (((Number)left).doubleValue() == ((Number)right).doubleValue()) == (this.selector == Equal); } return left.equals( right) == (this.selector == Equal); } </code> Reproducible: Always
I think that there is problem in proposed fix. You get EQUAL when you compare two NaN values of same type Double or Float. Because 'Double.NaN compareTo(Double.NaN)' return 0. Problem is when types of left and right values differ. (((Number)left).doubleValue() == ((Number)right).doubleValue()) return FALSE for both NaN values not true as compareTo(...) == 0 > if (((left instanceof Number) && (right instanceof Number)) && > (left.getClass() != right.getClass())) { > return (((Number)left).doubleValue() == > ((Number)right).doubleValue()) > == (this.selector == Equal); > }
I hope NaN is not real problem in real database world. (In reply to comment #1) > I think that there is problem in proposed fix. > You get EQUAL when you compare two NaN values of same type Double or Float. > Because 'Double.NaN compareTo(Double.NaN)' return 0. > > Problem is when types of left and right values differ. > (((Number)left).doubleValue() == ((Number)right).doubleValue()) > return FALSE for both NaN values not true as compareTo(...) == 0 > > > > if (((left instanceof Number) && (right instanceof Number)) && > > (left.getClass() != right.getClass())) { > > return (((Number)left).doubleValue() == > > ((Number)right).doubleValue()) > > == (this.selector == Equal); > > }
Setting target and priority. See the following page for details of the meanings of these: http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines
It's not clear to me what is meant by the comment: " think that there is problem in proposed fix. You get EQUAL when you compare two NaN values of same type Double or Float. Because 'Double.NaN compareTo(Double.NaN)' return 0." The line of code referred to in that comment should not be reached for Double or Float since both are Comparable and the comment metions "same type". Can you provide an example?
I understand the issue with NaN now. I'm undecided about whether this requires a change in EclipseLink.
Created attachment 185735 [details] patch with test
Checked in fix provided in bug with an ammendment to deal with NaN Reviewed By: Tom Ware - reviewed community-submitted fix Added DoesRelationConformTestSuite Tested with JPA and Core LRG
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink