Romain, On Tue, Dec 14, 2021 at 2:00 PM Romain Manni-Bucau <rmannibu...@gmail.com> wrote: > When I saw it - but it was something years ago so memory can be wrong - it > was because some database expected an operator expression and some others > were not supporting "where TRUE" evaluation so "where 1=1" (similarly for > <>) was a nice portable workaround.
I figured this must have been the reason. That's fine, just a visual curiosity, not a substance for these issues. > Now I agree that criteria API is not very well defined in both the spec and > openjpa and all combinations are not expected to work even if the API > enables it so maybe we should also check all the related cases are valid or > not from a spec point of view and ultimately from a SQL point of view. Well, the spec is what it is. Sure, it's limitations drive me crazy sometimes, but at least I can determine at some early stage what is generally possible and what's not, and we don't have much control over it. But the bugs that I constantly run into with OpenJPA when it comes to expressions/predicates are quite meddlesome. It takes time and some creativity to come up with queries that can be expressed with what the spec giveth, but when you pant and grunt and come up with complicated query only to have OpenJPA smash it with a bug like -2895 - that's quite unsettling, especially since OpenJPA doesn't even fail, just rewrites the query, and you have to unwind what happened. Just now I found out that "case(cb.isTrue(path)).when...." translates into "case 1 when" (well, really into "case ? when... [param=1]"). Who would have thought? Sure, some if not most of those can be overcome with workarounds - boolean function expressions can be replaced with cb.equal(f, true), the isTrue() in the case just above can be simply removed, and the argument used directly. But the time sunk into investigating and working around these issues aside, the way that I use the JPA framework is on a relatively low level. So, it's not simple to substitute one expression with another because the framework around it may be agnostic to data types, and making it produce different expressions based on not straight-forward logic is not trivial. Especially since one doesn't outright know whether the replacements would work. Now, on that note, I'd like to be able to fix bugs like this, and I was able to fix some in the past, that's why I'm asking for some info on that expression state - it's quite confusing without context. Thank you, Pawel. > > Romain Manni-Bucau > @rmannibucau <https://twitter.com/rmannibucau> | Blog > <https://rmannibucau.metawerx.net/> | Old Blog > <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> | > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book > <https://www.packtpub.com/application-development/java-ee-8-high-performance> > > > Le mar. 14 déc. 2021 à 12:51, Pawel Veselov <pawel.vese...@gmail.com> a > écrit : > > > Hello. > > > > I'm trying to fix these tickets as I ran into them the other day. > > -2894 looks relatively straightforward, and I have a working fix in > > https://github.com/veselov/openjpa/tree/OPENJPA-2894. > > > > However, I ran into -2895 as I was trying to test -2894, and fixing > > that looks a lot more complicated. > > > > Just to get -2894 to test, I've changed the TRUE/FALSE predicate > > definitions from using equality and non-equality expressions to using > > just constant true/false expressions. This blew out > > TestTypesafeCriteria true/false tests, though the problem is just in > > comparing the JPQL/CQL query text, otherwise those queries are > > correct. > > > > So, a question: is there a (non-obvious) reason why TRUE/FALSE > > Predicates should be defined as equality/non-equality, and can't be > > just TRUE/FALSE boolean expressions? Once -2895 is fixed, it won't be > > a problem, but still seeing (1==1) or (1<>1) instead of TRUE/FALSE > > (which also optimizes out in some cases) looks more clunky to me. > > > > For fixing -2895, the only solution that I could find is to properly > > implement toValue() for the predicates. For predicates simply wrapping > > an expression, it's trivial - just return toValue() of the > > expressions. But for real predicates (i.e., AND/OR/NOT operators), I > > would need to build a new Value class that represents them. > > > > However, I'm quite overwhelmed by the requirements of the Value class. > > I've tried modeling things after "Math" (similar syntax, binary > > operators) and "GeneralCaseExpression" (similar structure, since > > predicates can have more than two arguments), but I just don't > > understand the intention of the ExpState related methods, especially > > "calculateValue()" (what is this "other" value, and what's up with > > reciprocity on nested values that, say, Math does), and "length" (why > > does Math or GeneralCaseExpression return length of 1, what is the > > definition of "element" that the corresponding JavaDoc is talking > > about) > > > > So, two questions here: > > - is there a better way for creating predicate values? Or any better > > approach to solving -2895? > > - if not, can somebody offer insights on the Value methods contracts? > > > > Thank you! > > Pawel. > > -- With best of best regards Pawel S. Veselov