JDOQL Subquery failing


ebenzacar@...
 
Edited

I'm trying to get a complex query working with a subquery in the filter which is failing in the JDOQL Parser.  I have diluted it to a very simple use case with a subselect which is failing as well.  Please see the test-case on github.
I am fairly sure there is something which does not match expected syntax, but I am trying to follow the examples in the DN Docs, but the parser is still failing. 

My query is:

            Query q = pm.newQuery(Person.class);
q.setFilter("id == (select count(id) from Person p) "); // fails
List<Person> results = q.executeList();

and the exception I get is the following:

2021-07-23 15:31:44 INFO  JDO:92 - Exception thrown
expected ')' at character 15 in "id == (select id from Person p)"
org.datanucleus.store.query.QueryCompilerSyntaxException: expected ')' at character 15 in "id == (select id from Person p)"
at org.datanucleus.query.compiler.JDOQLParser.processPrimary(JDOQLParser.java:780)
at org.datanucleus.query.compiler.JDOQLParser.processUnaryExpression(JDOQLParser.java:643)
at org.datanucleus.query.compiler.JDOQLParser.processMultiplicativeExpression(JDOQLParser.java:569)
at org.datanucleus.query.compiler.JDOQLParser.processAdditiveExpression(JDOQLParser.java:540)
at org.datanucleus.query.compiler.JDOQLParser.processRelationalExpression(JDOQLParser.java:460)
at org.datanucleus.query.compiler.JDOQLParser.processAndExpression(JDOQLParser.java:437)
at org.datanucleus.query.compiler.JDOQLParser.processExclusiveOrExpression(JDOQLParser.java:423)
at org.datanucleus.query.compiler.JDOQLParser.processInclusiveOrExpression(JDOQLParser.java:409)
at org.datanucleus.query.compiler.JDOQLParser.processConditionalAndExpression(JDOQLParser.java:395)
at org.datanucleus.query.compiler.JDOQLParser.processConditionalOrExpression(JDOQLParser.java:376)
at org.datanucleus.query.compiler.JDOQLParser.processExpression(JDOQLParser.java:365)
at org.datanucleus.query.compiler.JDOQLParser.parse(JDOQLParser.java:88)
at org.datanucleus.query.compiler.JavaQueryCompiler.compileFilter(JavaQueryCompiler.java:600)
at org.datanucleus.query.compiler.JDOQLCompiler.compile(JDOQLCompiler.java:103)
at org.datanucleus.store.query.AbstractJDOQLQuery.compileGeneric(AbstractJDOQLQuery.java:392)
at org.datanucleus.store.query.AbstractJDOQLQuery.compileInternal(AbstractJDOQLQuery.java:450)
at org.datanucleus.store.rdbms.query.JDOQLQuery.compileInternal(JDOQLQuery.java:263)
at org.datanucleus.store.query.Query.executeQuery(Query.java:1936)
at org.datanucleus.store.query.Query.executeWithArray(Query.java:1864)
at org.datanucleus.store.query.Query.execute(Query.java:1846)
at org.datanucleus.api.jdo.JDOQuery.executeInternal(JDOQuery.java:439)
at org.datanucleus.api.jdo.JDOQuery.executeList(JDOQuery.java:345)
 




Does anyone have any ideas what I have done wrong with my subselect?  I've tried tracing through the `JDOQLParser` but without much success.

Thanks,

Eric


Andy
 

Ample examples of JDO subqueries in these tests. Note that none of the DN docs or these examples codes a subquery text into a "filter" clause of the parent query; they either single-string the whole query, or they use a variable for the subquery. They also always package-qualify all class names.


ebenzacar@...
 

Thanks for the link.  I'll take a closer look at them.

I did notice that none of the examples I had found added a subquery filter to a parent query.  I wasn't sure if that was for clarity or by design.

It would seem that appending subquery text into a filter clause of a parent query is not supported.  Would that be accurate?  Is that be a limitation or by design?

Like I said, I tried to step through the parser to identify where it was failing to provide a patch for it, but I was having to trouble  grasping the sequence  of the Lexer parser well enough.

Thanks

Eric


Andy
 
Edited

Intentional.
JDO Query programmatic "API" with separated items for "from", "filter", "result" etc never had subqueries in JDO1, and when subqueries were added in JDO2 they were specifiable using that programmatic "API" using addSubquery() and variables.
Single string JDOQL also came in at JDO2, with subqueries directly in the single string.

Clearly you could contribute handling, which would involve going to Query class where setFrom is called and parse it for a user including subqueries directly, and store those into the "subqueries" field. Then the primary query and each subquery are each compiled using their own individual JDOQLCompiler like now. No interest here. The other option in setFrom would be to search for the start of a subquery (e.g "SELECT ") and throw an exception informing the user of the error of their ways