Hi Craig,
I tried to identify assertions in the latest subquery specification, you
find my proposal below.
Regards Michael
-------------------------------------------
Subqueries
void addSubquery (Query subquery, String variableDeclaration,
String candidateCollectionExpression);
This method adds a subquery to this query. A subquery is composed as a
Query and subsequently attached to a different Query (the outer Query)
by calling this method. The String parameters are trimmed of white space.
*A14.6.2-50 [*The Query parameter instance is unmodified as a result of
the addSubquery or subsequent execution of the outer Query. Only some of
the parameter query parts are copied for use as the subquery. The parts
copied include the candidate class, filter, parameter declarations,
variable declarations, imports, ordering specification, uniqueness,
result specification, and grouping specification. The association with a
PersistenceManager, the candidate collection or extent, result class,
and range limits are not used.*]*
The variableDeclaration parameter is the name of the variable containing
the results of the subquery execution. *A14.6.2-51 [*If the same value
of variableDeclaration is used to add multiple subqueries, the subquery
replaces the previous subquery for the same named variable.*]*
*A14.6.2-52 [*If the subquery parameter is null, the variable is unset,
effectively making the variable named in the variableDeclaration
unbound.*]* *A14.6.2-53 [*If the trimmed value is the empty String, or
the parameter is null, then JDOUserException is thrown.
*A14.6.2-54 [*The candidateCollectionExpression is the expression from
the outer query that represents the candidates over which the subquery
is evaluated. If the trimmed value is the empty String, or the parameter
is null, then the candidate collection is the extent of the candidate
class.*]*
Non-correlated subqueries
*A14.6.2-55 [*If the subquery has no references to expressions in the
outer query the subquery is non-correlated.*]*
For example, to find employees who work more than the average of all
employees,
Query sub = pm.newQuery(Employee.class);
sub.setResult("avg(this.weeklyhours)");
Query q = pm.newQuery(Employee.class);
q.setFilter("this.weeklyHours > averageWeeklyhours");
q.addSubquery(sub, "double averageWeeklyhours", null);
Correlated subqueries
*A14.6.2-56 [*A correlated subquery is a subquery which contains
references to expressions in the outer query. If the correlation can be
expressed as a restriction of the candidate collection of the subquery,
no parameters are needed.*]*
For example, to find employees who work more than the average of their
department employees:
Query sub = pm.newQuery(Employee.class);
sub.setResult("avg(this.weeklyhours)");
Query q = pm.newQuery(Employee.class);
q.setFilter("this.weeklyhours> averageWeeklyhours");
q.addSubquery(sub, "double averageWeeklyhours",
"this.department.employees");
*A14.6.2-57 [*If the correlation cannot be expressed as a restriction of
the candidate collection, the correlation is expressed as one or more
parameters in the subquery which are bound to expressions of the outer
query.*]*
void addSubquery(String variableDeclaration,
Query subquery, String candidateCollectionExpr, String parameter);
void addSubquery(String variableDeclaration,
Query subquery, String candidateCollectionExpr, String[] parameters);
void addSubquery(String variableDeclaration,
Query subquery, String candidateCollectionExpr, Map parameters);
The parameters in the above methods binds parameters in the subquery to
expressions in the outer query. String parameters are trimmed of white
space. The single String version of the method binds the named
expression to the single parameter in the subquery. The String[] version
of the method binds the named expressions in turn to parameters in the
order in which they are declared in the subquery, or in the order they
are found in the filter if not explicitly declared in the subquery. The
Map version of the method treats the key of each map entry as the name
of the parameter in the subquery, with or without the leading “:”, and
the value as the name of the expression in the outer query. If the
trimmed expression is the empty String for either the parameter or the
value of the String[], or for any map key or value, that expression is
ignored.
For example, to find employees who work more than the average of the
employees in their department having the same manager:
Query sub = pm.newQuery(Employee.class);
sub.setResult("avg(this.weeklyhours)");
sub.setFilter("this.manager == :manager");
Query q = pm.newQuery(Employee.class);
q.setFilter("this.weeklyHours > averageWeeklyhours");
q.addSubquery(sub, "double averageWeeklyhours",
"this.department.employees", "this.manager");
The parameter in the subquery “:manager” is bound to the expression
“this.manager” in the context of the outer query.
--
[EMAIL PROTECTED] Engineering GmbH Tel.: +49/(0)30/235 520-33
Buelowstr. 66 Fax.: +49/(0)30/217 520-12
10783 Berlin mailto:[EMAIL PROTECTED]
Geschaeftsfuehrung: Anna-Kristin Proefrock
Sitz Berlin, Amtsgericht Charlottenburg, HRB 564 52