DataNucleus started out as JPOX, which started as TJDO. This had support for RDBMS, and in particular JDOQL querying. Unfortunately the TJDO process for JDOQL was a sequential parse of the query string, generating the SQL for the query. While we extended this a lot during the JPOX lifetime this was always limited by the underlying API available and the process (not being able to easily inspect the query to see if something has AND or OR at the same level, and hence decide if we should do an EXISTS, or an INNER JOIN etc etc). It was always planned to rewrite it at some point, particularly to make the query compilation available to other types of datastores, but also to try to resolve some of the problems.
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");
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.