Hi Michael,Thanks for these comments. I've updated the specification dated 2008-02-15. Please review the changes.
On Feb 4, 2008, at 12:09 PM, Michael Bouschen wrote:
Hi Craig,I went through the query chapter of the January 18 version of the JDO spec and would like to propose a few changes to be added to describe subqueries:- section "14.3 Architecture: Query"The subsection titled "Other elements in queries include:" should get a new bullet about subqueries.
subqueries. Some aspects of the filter might best be described by a subquery, whose result is used as part of an expression of the outer query. The subquery might use parameters or expressions of the outer query and might range over the extent of a class in the datastore.
I've also updated the section on serializing query instances:A14.3-7 [The class implementing the Query interface must be serializable. The serialized fields include the candidate class, the filter, parameter declarations, variable declarations, imports, ordering specification, uniqueness, result specification, grouping specification, result class, and subqueries.] The candidate collection, limits on size, and number of skipped instances are not serialized. A14.3-8 [If a serialized instance is restored, it loses its association with its former PersistenceManager.]
-section "14.6 Query Interface"The subsection "Query element binding" should mention the 4 new methods addSubquery to support subqueries.
I've added this text immediately after setRange(String fromincltoexcl)
void addSubquery (Query subquery, String variableDeclaration,
String candidateCollectionExpression);
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);
These methods specify a subquery to become part of this query
- section "14.6.13 Single-string Query element binding"I propose to mention subqueries in this section. Maybe after the sentence "<filter> is the filter as in 14.6.2.", something like:The filter in the single String form may include subqueries. A suquery has the following structure:select subquery-result-clause from subquery-from-clause where filter decls The subquery-result-clause consists of an optional keyword distinct followed by a single expression.The subquery-from-clause may have one of two forms:- A candidate class name followed by an optional alias definition followed by an optional exclude subclasses- A field access expression followed by an optional alias definitionAn alias definition consists of an optional keyword as followed by an identifier. This identifier may be used instead of this to access the candidate instances of the subquery.
I've replaced the filter description with:<filter> is the filter as in 14.6.2. The filter in the single String version might include subqueries. A subquery has the following structure: select <subquery-result-clause> from <subquery-from-clause> [where <filter>] [variables <variables-clause> ] [parameters <parameters- clause> [<imports-clause>] The subquery-result-clause consists of an optional keyword distinct followed by a single expression.
The subquery-from-clause may have one of two forms:A candidate class name followed by an optional alias definition followed by an optional exclude subclasses
A field access expression followed by an optional alias definitionAn alias definition consists of an optional keyword as followed by an identifier. This identifier is used instead of this to access the candidate instances of the subquery.
- section "14.10 Examples"How about adding one or two subquery examples? We could use the TCK subqueries as examples, e.g. - Class NonCorrelatedSubqueries method runTestSubqueries01: select employees who work more than the average of all employees: SELECT FROM com.xyz.hr.Employee WHERE this.weeklyhours > (SELECT AVG(e.weeklyhours) FROM com.xyz.hr.Employee e) - Class CorrelatedSubqueriesWithParameters method runTestSubqueries01: select employees who work more than the average of the employees in their department having the samemanager:SELECT FROM "com.xyz.hr.Employee WHERE this.weeklyhours > (SELECT AVG(e.weeklyhours) FROM this.department.employees e WHERE e.manager == this.manager)
I've added these examples: 14.10.18 Non-correlated subqueryThis query returns names of employees who work more than the average of all employees:
// single string form Query q = pm.newQuery(Employee.class);q.setFilter("this.weeklyhours > (select avg(e.weeklyhours) from com.xyz.hr.Employee e)");
q.setResult(e.name);
Collection names = q.execute();
Iterator it = names.iterator();
while (it.hasNext()) {
String name = (String)it.next();
...
}
// subquery instance form
Query q = pm.newQuery(Employee.class);
q.setFilter("this.weeklyhours > average_hours");
Query subq = pm.newQuery(Employee.class);
subq.setFilter(“select avg(weeklyhours)”);
q.setResult(e.name);
q.setSubquery(subq, “double average_hours”, null);
Collection names = q.execute();
Iterator it = names.iterator();
while (it.hasNext()) {
String name = (String)it.next();
...
}
<query name=”noncorrelated_subquery”>
[!CDATA[
select from com.xyz.hr.Employee where
this.weeklyhours >
(select avg(e.weeklyhours) from com.xyz.hr.Employee e)
]]
</query>
14.10.19 Correlated subquery
This query returns names of employees who work more than the average
of employees in the same department having the same manager. The
candidate collection of the subquery is the collection of employees in
the department of the candidate employee and the parameter passed to
the subquery is the manager of the candidate employee.
// single string form
Query q = pm.newQuery(Employee.class);
q.setFilter("select from "com.xyz.hr.Employee where
this.weeklyhours >
(select AVG(e.weeklyhours) from this.department.employees e
where e.manager == this.manager)");
q.setResult(e.name);
Collection names = q.execute();
Iterator it = names.iterator();
while (it.hasNext()) {
String name = (String)it.next();
...
}
// subquery instance form
Query q = pm.newQuery(Employee.class);
q.setFilter("this.weeklyhours > average_hours");
Query subq = pm.newQuery(Employee.class);
subq.setFilter(“this.manager == :manager”);
subq.serResult(“avg(weeklyhours)”);
q.setResult(e.name);
q.setSubquery(subq, “double average_hours”,“department.employees”,
“this.manager”);
Collection names = q.execute();
Iterator it = names.iterator();
while (it.hasNext()) {
String name = (String)it.next();
...
}
<query name=”correlated_subquery”>
[!CDATA[
select from com.xyz.hr.Employee where
this.weeklyhours >
(select AVG(e.weeklyhours) from this.department.employees e
where e.manager == this.manager)
]]
</query>
Regards Michael -- [EMAIL PROTECTED] Engineering GmbH Tel.: +49/(0)30/235 520-33 Buelowstr. 66 Fax.: +49/(0)30/217 520-1210783 Berlin mailto:[EMAIL PROTECTED] Geschaeftsfuehrung: Martin WeberSitz Berlin, Amtsgericht Charlottenburg, HRB 564 52
Craig Russell Architect, Sun Java Enterprise System http://java.sun.com/products/jdo 408 276-5638 mailto:[EMAIL PROTECTED] P.S. A good JDO? O, Gasp!
smime.p7s
Description: S/MIME cryptographic signature
