jamesfredley commented on code in PR #16875:
URL: https://github.com/apache/grails-core/pull/16875#discussion_r4492954736


##########
grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/query/Query.java:
##########
@@ -691,6 +691,110 @@ protected FetchType fetchStrategy(String property) {
         return FetchType.LAZY;
     }
 
+    /**
+     * Runs the subqueries inside the given criteria and returns a copy of the 
criteria that holds their
+     * results, for datastores that cannot evaluate a subquery themselves 
(MongoDB, Neo4j). The criteria
+     * passed in are never changed, so a query that is executed twice runs its 
subqueries twice.
+     *
+     * <p>A comparison ({@code ==}, {@code !=}, {@code >}, {@code >=}, {@code 
<}, {@code <=}) against a
+     * subquery, such as {@code age > avg(age)}, takes the one value the 
subquery returns, and {@code in}
+     * and {@code notIn} take all of them. A subquery that returns more than 
one row for a comparison is
+     * rejected. {@code exists}, {@code notExists} and the {@code all} and 
{@code some} forms are rejected
+     * with an {@link InvalidDataAccessResourceUsageException}, as they are 
not supported.</p>
+     *
+     * @param criteria the criteria of this query
+     * @return the same instance when it holds no subquery, otherwise a copy 
with the subqueries resolved
+     * @throws InvalidDataAccessResourceUsageException for a form that cannot 
be resolved
+     * @since 8.0.1
+     */
+    protected Junction resolveSubqueries(Junction criteria) {
+        return (Junction) resolveSubqueries((Criterion) criteria);
+    }
+
+    private Criterion resolveSubqueries(Criterion criterion) {

Review Comment:
   address { inList('city', City.where {}.property('name')) } leaves the 
subquery unresolved, because an association block is not a junction. The query 
sends $in: [] and returns no person, although a person lives in Paris. Resolve 
the criteria inside the association block too.



##########
grails-data-mongodb/core/src/main/groovy/org/grails/datastore/mapping/mongo/query/MongoQuery.java:
##########
@@ -486,7 +486,8 @@ public Document getMongoQuery() {
     }
 
     @Override
-    protected List executeQuery(final PersistentEntity entity, final Junction 
criteria) {
+    protected List executeQuery(final PersistentEntity entity, final Junction 
queryCriteria) {
+        final Junction criteria = resolveSubqueries(queryCriteria);

Review Comment:
   get() still calls getMongoQuery(), which reads the original criteria. 
inList('firstName', Person.where { age > 40 }.property('firstName')).get() 
returns null, while list() returns Homer and Barney. Build the single-result 
filter from the resolved criteria.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to