db-jdo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Craig L Russell <Craig.Russ...@Sun.COM>
Subject Re: JDO spec remarks (subqueries)
Date Fri, 08 Feb 2008 19:50:54 GMT
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 definition
> An 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 definition
An 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 same
> manager:
> 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 subquery
This 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
>
> -- 
> Tech@Spree Engineering GmbH  Tel.: +49/(0)30/235 520-33
> Buelowstr. 66                Fax.: +49/(0)30/217 520-12
> 10783 Berlin                 mailto:mbo.tech@spree.de  
> Geschaeftsfuehrung: Martin Weber
> Sitz Berlin, Amtsgericht Charlottenburg, HRB 564 52
>

Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Mime
View raw message