-
-
Notifications
You must be signed in to change notification settings - Fork 263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong junction generated when using OR with EXISTS subquries #3305
Comments
Did you try moving the QEaObject(database)
.alias("parent") // <!-- HERE - outside the OR
.or()
.exists( ...
.eaGuid.isIn(containerPackageSubQuery.select(QEaPackage._alias.eaGuid).query())
.endOr() |
yeah, that was one of the first things that occurred to me, but the result is the same |
You need to move the Once you do that ... then you need to produce 2 other tests with 1 not using exists and 1 swapping the order of the exists and isIn. Then report back on those 3 tests and update the description on this bug report to reflect what works/passes and what does not pass. |
updated both the original comment and the test file. did I get it right? |
Yes - awesome. Now this bug is in TQRootBean (Type Query Root Bean) in that we see: public R exists(Query<?> subQuery) {
query.where().exists(subQuery); // <!-- The query.where() is the bug here !!
return root;
} And the fix for this would be for it to be instead: public R exists(Query<?> subQuery) {
this.peekExprList().exists(subQuery); // <!-- Fix uses peekExprList()
return root;
} The fix is to replace So the bug here that the exists(subQuery) expression is always added to the top level ExpressionList when we instead want it added to the current ExpressionList that represents the OR in this case. [An ExpressionList is a list of expressions added together by either We can also note that the notExists(subQuery) also has this same bug and that these bugs are specifically for query beans / these 2 bugs are on TQRootBean. |
Now, do you want to have a go at doing a PR for this one or would you rather leave it to me? If you do a PR that just has the fix I'll add a failing test case to the PR (we want the failing test - typically we would assert on the generated SQL asserting that the where clause has the expected clause with the exists inside the OR). |
I can definitely give it a try. I'm just not sure I understand about the failing test - do you mean it should fail before I apply the fix (and pass afterwards), or should it actually assert the current behavior and fail after I apply it (as some sort of paper trail of the development)? |
Yes - this one. |
So, I tried to do this fix including the test (only for First, I didn't manage to succeed running the test from IDEA (using the "play" button). First I had to add the and couldn't get rid of it. I tried to pass When I was able to run the test file, I added this test case, which after applying your fix, almost passes - the order is correct and the right junction is used - but it seems I'm hitting some other strange issue - although I specify the "parent-child" join condition as |
Ah yeah. With ebean we run all the tests using classpath and not using module-path. [Long story but yes using module-path when running tests is more pain and we basically don't do that, sorry you went through that pain there]. For running ebean tests with IntelliJ IDEA we have:
... which is hidden at the very bottom of the README at https://github.com/ebean-orm/ebean#intellij-idea
This is that there is a name collision in that Great work, well done. |
Oh, ok, I'm glad there's a way to fix this then. I went through the howto-test.md, but it didn't occur to me to look in the general readme.
Makes sense. I keep forgetting that even though it's called
Glad to be marginally useful, maybe in a few years, I'll actually be able to come up with the solution myself :) For now, I'm very grateful for your guidance. BTW, do you have any ideas concerning this?
I know I can replace the select from x parent where exists (select 1 from x child where child.parent_id = parent.id and ...) I can do select from x where id in (select parent_id from x where ...) which I can build easily with the typed querybean API, but I'm not sure this is as performant as the |
Expected behavior
When I do a query like this
I expect the two WHERE clauses to be joined using OR junction, but AND is generated instead.
Actual behavior
The actual generated query is
As you can se, it has
AND
instead ofOR
.Steps to reproduce
I reproduced this issue in a minimal test repo here https://github.com/Incanus3/ebean-test/blob/main/ea/db/src/test/kotlin/cz/sentica/qwazar/ea/db/ExistSubqueryJunctionsTest.kt#L33
Rationale behind this use-case
Our application accesses a database, whose schema is managed by Enterprise Architect, and is thus out of our control. In EA there are two kinds of parent-child relationships:
EaObject
references the parentEaObject
usingchild.parent_id = parent.object_id
EaPackage
is referenced by the containedEaObject.package_id
EaPackage
has an associatedEaObject
which has the sameEA_GUID
as theEaPackage
(yeah, no pkey relationship there)so if we want to find all
EaObjects
wich "contain" the givenEaObject
(either directly as parents or though a package), we must do it using a query like this. I concede that ideally I shouldn't need a query like this - we could create a view that would precompute these parent-child and package-contained object relationship, nevertheless I still think this is a bug and you should know about it.Side question
Is there a way to avoid using
raw
when doing these exists subqueries where the subquery needs to reference the "parent" query?The text was updated successfully, but these errors were encountered: