DataNucleus AccessPlatform 1.1 now has a generic query compilation process (proof of concept written by Erik, and extended by me to come close to complete compilation, with some minor patch contributions from others). The generic query compilation results in expression "trees" for each component of the query; these are easier to analyse and hence to generate any native query from, for the datastore being used. This generic query compilation is what is used by all datastore plugins (with the exception of legacy RDBMS). In addition it includes an "in-memory" query evaluator. This is intended to take in a collection of candidates for the query, and evaluate the filter clause using the data in those instances. This in-memory evaluation works for many things but currently doesn't yet support Collection.contains, Map.containsKey, etc and also variables.
AccessPlatform 1.1 RDBMS plugin also includes code for something referred to as "JDOQL2". This is not a new query language, but instead an alternative implementation of JDOQL for RDBMS datastores. It uses the underlying generic query compilation (like for the other datastores), and has a step converting this into SQL. This new implementation has a few key concepts
- Uses a newly written SQL API to generate the statement
- SQL statement strings are JDBC-compatible, having parameters only where the user query has them (TJDO SQL didn't follow this)
- Users have control over the naming scheme for table aliases in the SQL
- Implementation of support for JDOQL "methods" via a plugin-point, so you could write a plugin for Collection.size(), for example, if you wanted.
- Support is provided for all aggregate functions, the main String methods, the main Date methods, JDOHelper.getObjectId, Collection.size(), Collection.isEmpty(), Map.size(), Map.isEmpty(), and some others ... but not yet Collection.contains/Map.containsKey/Map.containsValue/Map.get
- All queries compiled using JDOQL2 are cached, meaning they are not compiled again for that PMF
- With the legacy JDOQL implementation, a query would be compiled at execute (and also at compile if compile() was called). In JDOQL2 it is only compiled once.
- JDOQL2 implements the JDO2.3 query timeout/cancel API, so you can, in principle, cancel queries if they were submitted from a different thread and are still running. This would then cancel the underlying JDBC query (assuming the JDBC driver supports it)
- Queries will retrieve not just non relation fields (like with legacy JDOQL) but also any 1-1 fields, hence avoiding the "1+N" problem
JDOQL2 is there for you to use and try, just do something like (for RDBMS)
Query q = pm.newQuery("JDOQL2",
"SELECT FROM mydomain.MyClass WHERE field1 < :param");
q.execute(value);
and see what you find. The idea is that this will replace (legacy) JDOQL for RDBMS sometime in the AccessPlatform 2.0 lifecycle; maybe not if time doesn't allow it.
Your example code shows how to use JDOQL2 in the 'SQL like' mode starting "SELECT blah".
ReplyDeleteCan JDOQL2 be used in the standard JDO mode:
eg,
pm.newQuery(com.acme.MyClass.class);
and if so how do we tell it to use the JDOQL2 implementation instead of the current implementation?
datanucleus.query.JDOQL.implementation=JDOQL2
ReplyDelete