Apache JDO Project - Re: JDOQL Subquery proposals

This is Interesting: Free IT Magazines  
Home > Archive > Apache JDO Project > September 2006 > Re: JDOQL Subquery proposals





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Re: JDOQL Subquery proposals
Michael Bouschen

2006-09-24, 7:11 pm

Hi Wes,

thanks for the feedback, it's definitely not too late.

I like your proposal. It allows subqueries being supported in both the
SSJDOQL and the query API. I like the the idea of explicitly setting
subquery's candidate collection by passing an expression of the outer
query (and use the same mechanism for the parameters of the subquery).
This solves the biggest problem I had with using a separate Query
instance for the subquery: now the subquery instance is self-contained
and compiles, because it does not explicitly use an expression from the
outer query.

I'm just wondering whether we could find a more intuitive syntax,
because name(candidateExpression[,parameterExpression...]) looks more
like a method than a variable. Furthermore, as a corner case, it might
be possible that a query uses more than one subquery. All the subqueries
would have to be defined in a single call of outer.declareVariables. So
how about, if we introduce a new method called addSubquery to bind a
single subquery to the outer query. The method takes separate arguments
for the candidate collection expression and the parameters (if any).
Actually the parameter handling could be very similar to the parameters
of the execute call:
addSubquery(String variableDeclaration, Query subquery, String
candidateCollectionExpr);
addSubquery(String variableDeclaration, Query subquery, String
candidateCollectionExpr, String parameter);
addSubqueryWithArray(String variableDeclaration, Query subquery,
String candidateCollectionExpr, String[] parameters);
addSubqueryWithMap(String variableDeclaration, Query subquery, String
candidateCollectionExpr, Map parameters);

Looking at the first example from below, the definition of the subquery
would be the same. The only line that changes is the declareVariable
call. It is replaced by:
q.addSubquery(""float averageSalary", sub, "this.department.employees");

Just for completeness we should add a method to clear the subqueries,
such that you can reuse the outer query and bind new subqueries for
another execute call:
clearSubqueries();

What do you think?

If we think the above is option I would come up with an updated summary
of JDOQL changes to support subqueries and updated version of the sample
queries.

Regards Michael
[vbcol=seagreen]
> I'm ridiculously late in responding to this thread but if I may be so
> bold, I'll make a further suggestion.
>
> I like everything about the proposed approach except the requirement
> that subquery definitions must resort to single-string JDOQL syntax,
> even when using the API-based methods. I think this introduces
> asymmetry and discourages reuse and modularity.
>
> I would really like to see the ability to map variables to (sub)Query
> objects. There are two new capabilities introduced in the SSJDOQL
> version, and my opinion is that the API should match these feature by
> feature. The two features are:
> (1) The ability for a subquery to use an expression defined on the
> outer query as its candidate set.
> (2) The ability for a subquery to use expressions defined on the outer
> query as parameters.
>
> Therefore, for parity, we need an API-based way to declare these
> mappings, so that subqueries can be assigned both their candidate
> collections and their parameters dynamically.
>
> I propose an overloaded version of declareVariables that allows
> mapping variable names used in the outer query to (sub)Query instances
> that are correlated with candidates and parameters.
>
> void declareVariables(String variableList, Query... subquery)
>
> The variable declaration syntax should be extended to allow
> parameterized variables of the form
> "name(candidateExpression[,parameterExpression...])". "name" defines
> a variable name in the query; "candidateExpression" defines an
> expression (rooted in the namespace of the outer query) for the
> candidate extent to be bound to the subquery, where "null" signifies
> that the subquery candidate set is not being limited.
> "parameterExpression" identifies dynamic values for parameters
> declared by the subquery, again rooted in the namespace of the outer
> query doing the binding.
>
> To touch up Michael's examples:
>
> Select employees who make more than the average of their department
> employees?
>
> Single-string JDOQL:
> SELECT FROM Employee WHERE this.salary > (SELECT AVG(e.salary) FROM
> this.department.employees e)
> Query API:
> Query q = pm.newQuery(Employee.class);
> q.setFilter("this.salary > averageSalary");
>
> // Subquery definition is generic: for a given set of Employees,
> return the average salary
> Query sub = pm.newQuery(Employee.class);
> sub.setResult("avg(salary)");
>
> // Bind the subquery to the master query by identifying the candidate set
> q.declareVariables("float averageSalary(this.department.employees)",
> sub);
>
>
> Single-string JDOQL:
> SELECT FROM Employee WHERE this.salary >
> (SELECT AVG(e.salary) FROM this.department.employees e WHERE
> e.payScale == this.payScale)
>
> Query API:
> Query q = pm.newQuery(Employee.class);
> q.setFilter("this.salary > averageSalary");
>
> // This subquery generically defines the average salary of a set of
> Employees at a given PayScale
> Query sub = pm.newQuery(Employee.class);
> sub.setFilter("this.payScale == ps");
> sub.declareParameters("PayScale ps");
> sub.setResult("avg(salary)");
>
> // Bind both a candidate set and the payScale parameter.
> q.declareVariables("float averageSalary(this.department.employees,
> this.payScale)", sub);
>
>
> Single-string JDOQL:
> SELECT FROM Employee WHERE this.salary > (SELECT AVG(e.salary) FROM
> Employee e)
> SELECT FROM Employee WHERE this.salary > (SELECT AVG(this.salary)
> FROM Employee)
>
> Query API:
> Query q = pm.newQuery(Employee.class);
> q.setFilter("this.salary > averageSalary");
> Query sub = pm.newQuery(Employee.class);
> sub.setResult("avg(salary)");
> // The null value indicates that we're not overriding the candidates
> for the subquery
> // and thus it uses the entire extent of Employee
> q.declareVariables("float averageSalary(null)", sub);
>
>
>
> Single-string JDOQL:
> SELECT FROM Employee WHERE this.name == 'Joe' && this.salary > (SELECT
> AVG(e.salary) FROM Employee e)
>
> Query API:
> Query q = pm.newQuery(Employee.class);
> q.setFilter("this.name == 'Joe' && this.salary > averageSalary");
>
> // This subquery generically defines "the average of all employeees"
> Query sub = pm.newQuery(Employee.class);
> sub.setResult("avg(salary)");
>
> // Note we could have reused the query instance from the previous
> example.
> q.declareVariables("float averageSalary(null)", sub);
>
>
> Single-string JDOQL:
> SELECT FROM Employee WHERE this.name == 'Joe' && this.salary >
> (SELECT AVG(e.salary) FROM Employee e WHERE e.payScale ==
> this.payScale)
>
> Query API:
> Query q = pm.newQuery(Employee.class);
> q.setFilter("this.name == 'Joe' && this.salary > averageSalary");
>
> // Note that this is the same subquery instance as the previous pay
> scale example
> Query sub = pm.newQuery(Employee.class);
> sub.setFilter("payScale == ps");
> sub.declareParameters("PayScale ps");
> sub.setResult("avg(salary)");
>
> q.declareVariables("float averageSalary(null)", sub);
>
>
> Single-string JDOQL:
> SELECT FROM Employee WHERE this.salary > (SELECT AVG(e.salary) FROM
> Employee e WHERE e.payScale == this.payScale)
>
> Query API:
> Query q = pm.newQuery(Employee.class);
> q.setFilter("this.salary > averageSalary");
>
> // Same again
> Query sub = pm.newQuery(Employee.class);
> sub.setFilter("ps == this.payScale");
> sub.declareParameters("PayScale ps");
>
> q.declareVariables("float averageSalary(null, this.payScale)", sub);
>
> I'd like to hear other ideas for the exact syntax, but what do you
> think of the general concept?
>
> Wes
>
>
> Michael Bouschen wrote:
>


--
Michael Bouschen Tech@Spree Engineering GmbH
mailto:mbo.tech@spree.de http://www.tech.spree.de/
Tel.:++49/30/235 520-33 Buelowstr. 66
Fax.:++49/30/2175 2012 D-10783 Berlin


Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com