[ 
https://issues.apache.org/jira/browse/OPENJPA-2895?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Pawel Veselov updated OPENJPA-2895:
-----------------------------------
    Summary: Predicates largely can not be used as value expressions  (was: 
Predicates largely can not be used as expressions)

> Predicates largely can not be used as value expressions
> -------------------------------------------------------
>
>                 Key: OPENJPA-2895
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-2895
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: criteria, jdbc
>    Affects Versions: 3.1.2, 3.2.0
>            Reporter: Pawel Veselov
>            Priority: Major
>
> Here is how I stumbled upon this:
> Code:
> {code:java}
>             CriteriaQuery<Order> q = cb.createQuery(Order.class);
>             Root<Order> o = q.from(Order.class);
>             q.where(cb.function("COALESCE", Boolean.class, 
> o.get(Order_.name), cb.literal(false)));
>             q.select(o);
>             List<Order> orders = em.createQuery(q).getResultList();
> {code}
> Result of {{q.toString():}} (that looks quite OK)
> {code:sql}
> SELECT o FROM Order o WHERE COALESCE(o.name,1 <> 1)
> {code}
> What gets sent to Derby (output of JPA query log):
> {noformat}
> 1162  test  TRACE  [main] openjpa.jdbc.SQL - <t 402978317, conn 981487964> 
> executing prepstmnt 1437983537 SELECT t0.id, t0.CNT, t1.id, t1.accountNum, 
> t2.id, t2.city, t2.country, t2.county, t2.state, t2.street, t3.userid, 
> t3.DTYPE, t3.age, t3.compName, t3.creditRating, t3.name, t2.zipCode, 
> t1.balanceOwed, t1.creditRating, t1.filledOrderCount, t1.firstName, 
> t1.lastName, t1.name, t1.status, t0.delivered, t0.name, t0.orderTs, 
> t0.quantity, t0.totalCost FROM CR_ODR t0 LEFT OUTER JOIN CR_CUST t1 ON 
> t0.CUSTOMER_ID = t1.id LEFT OUTER JOIN CR_ADDR t2 ON t1.ADDRESS_ID = t2.id 
> LEFT OUTER JOIN CompUser t3 ON t2.id = t3.ADD_ID WHERE (COALESCE(t0.name, ?) 
> = ?) [params=(int) 1, (int) 1]
> 1162  test  TRACE  [main] openjpa.jdbc.SQL - <t 402978317, conn 981487964> [0 
> ms] spent
> {noformat}
> Obviously, the query is wrong, as it inverted the result.
> This is standing in the way of my testing OPENJPA-2894, as COALESCE is the 
> only boolean function I could think of that Derby has...
> Mind you, the analysis below is over 3.1.2 code base, but so far that's the 
> version I'm sticking to.
> The root cause is that the function argument is an expression, specifically, 
> in this case, a predicate. Because it's a function argument, it needs to be 
> translated to {{Value}}. There is a special method, 
> {{PredicateImpl.toValue()}}, which only works for a handful of predicates. It 
> definitely doesn't work on most binary operators. 
> {{PredicateImpl.toValue()}} returns TRUE (which is what happens here), if the 
> predicate has no parts. Otherwise, it throws a "not implemented" error. 
> However, a lot of predicates, at least {{BinaryLogicalExpression}}, which 
> {{Equals}}, and others, extend from, do not "add" their sub-expressions to 
> {{_exps}} list, and don't implement {{toValue{}}} method. Not only that's not 
> caught, it also causes bugs like this.



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to