use of org.datanucleus.query.compiler.QueryCompilation in project tests by datanucleus.
the class JDOQLCompilerTest method testFilterImplicitVariable.
/**
* Test for use of an implicit variable in the filter.
*/
public void testFilterImplicitVariable() {
// Test use of implicit variable in filter
JavaQueryCompiler compiler = null;
QueryCompilation compilation = null;
try {
compiler = new JDOQLCompiler(nucCtx, nucCtx.getClassLoaderResolver(null), null, Product.class, null, "notaField == 2", null, null, null, null, null, null, null, null);
compilation = compiler.compile(null, null);
} catch (NucleusUserException ne) {
// TODO Debatable if this should throw a JDOUserException since the "notaField" is not bound, nor typed
NucleusLogger.QUERY.error("Exception thrown during compilation", ne);
fail("compilation of filter with valid field threw exception : " + ne.getMessage());
}
Expression expr = compilation.getExprFilter();
assertTrue("Compiled expression should have been DyadicExpression but wasnt", expr instanceof DyadicExpression);
DyadicExpression dyExpr = (DyadicExpression) expr;
assertTrue("Compiled left expression should be VariableExpression but isnt", dyExpr.getLeft() instanceof VariableExpression);
assertTrue("Compiled right expression should be Literal but isnt", dyExpr.getRight() instanceof Literal);
VariableExpression left = (VariableExpression) dyExpr.getLeft();
assertEquals("Variable expression name is wrong", left.getId(), "notaField");
Literal right = (Literal) dyExpr.getRight();
assertEquals("Literal has wrong value", new Long(2), right.getLiteral());
}
use of org.datanucleus.query.compiler.QueryCompilation in project tests by datanucleus.
the class JDOQLCompilerTest method testFilterWithNegateExpression.
/**
* Tests for "!(expression)".
*/
public void testFilterWithNegateExpression() {
JavaQueryCompiler compiler = null;
QueryCompilation compilation = null;
try {
compiler = new JDOQLCompiler(nucCtx, nucCtx.getClassLoaderResolver(null), null, Product.class, null, "!(price > 32)", null, null, null, null, null, null, null, null);
compilation = compiler.compile(new HashMap(), null);
} catch (NucleusException ne) {
NucleusLogger.QUERY.error("Exception thrown during compilation", ne);
fail("compilation of filter with valid field threw exception : " + ne.getMessage());
}
Expression expr = compilation.getExprFilter();
assertTrue("Compiled expression should have been DyadicExpression but wasnt", expr instanceof DyadicExpression);
DyadicExpression dyExpr = (DyadicExpression) expr;
assertTrue("Compiled left expression should have been DyadicExpression but wasnt", dyExpr.getLeft() instanceof DyadicExpression);
assertNull("Compiled right expression should have been null but wasnt", dyExpr.getRight());
assertEquals("Expression operator is wrong", Expression.OP_NOT, dyExpr.getOperator());
DyadicExpression leftExpr = (DyadicExpression) dyExpr.getLeft();
assertTrue("Left (left) should be PrimaryExpression but isnt", leftExpr.getLeft() instanceof PrimaryExpression);
assertTrue("Left (right) should be Literal but isnt", leftExpr.getRight() instanceof Literal);
assertEquals("Left expression operator is wrong", Expression.OP_GT, leftExpr.getOperator());
PrimaryExpression primExpr = (PrimaryExpression) leftExpr.getLeft();
assertEquals("Left (left) expression has incorrect number of tuples", 1, primExpr.getTuples().size());
assertEquals("Left (left) expression 'id' is incorrect", "price", primExpr.getId());
Literal lit = (Literal) leftExpr.getRight();
assertTrue("Left (right) expression literal is of incorrect type", lit.getLiteral() instanceof Long);
assertEquals("Left (right) expression literal has incorrect value", 32, ((Long) lit.getLiteral()).longValue());
}
use of org.datanucleus.query.compiler.QueryCompilation in project datanucleus-api-jdo by datanucleus.
the class JDOQLTypedQueryImpl method getInternalQuery.
/**
* Convenience method to generate an internal DataNucleus Query and apply the generic compilation to it.
* @return The internal DataNucleus query
*/
protected Query getInternalQuery() {
// Create a DataNucleus query and set the generic compilation
Query internalQuery = ec.getStoreManager().newQuery(Query.LANGUAGE_JDOQL, ec, toString());
if (ec.getFlushMode() == FlushMode.QUERY) {
// Flush mode implies flush all before executing the query so set the necessary property
internalQuery.addExtension(Query.EXTENSION_FLUSH_BEFORE_EXECUTION, Boolean.TRUE);
}
internalQuery.setIgnoreCache(ignoreCache);
if (extensions != null) {
internalQuery.setExtensions(extensions);
}
if (fetchPlan != null) {
internalQuery.setFetchPlan(fetchPlan.getInternalFetchPlan());
}
if (serializeRead != null) {
internalQuery.setSerializeRead(serializeRead);
}
if (datastoreReadTimeout != null) {
internalQuery.setDatastoreReadTimeoutMillis(datastoreReadTimeout);
}
if (datastoreWriteTimeout != null) {
internalQuery.setDatastoreWriteTimeoutMillis(datastoreWriteTimeout);
}
if (!subclasses) {
internalQuery.setSubclasses(false);
}
if (type == QueryType.SELECT) {
internalQuery.setType(Query.QueryType.SELECT);
if (resultDistinct != null) {
internalQuery.setResultDistinct(resultDistinct.booleanValue());
}
internalQuery.setResultClass(resultClass);
internalQuery.setUnique(unique);
if (candidates != null) {
internalQuery.setCandidates(candidates);
}
} else if (type == QueryType.BULK_UPDATE) {
internalQuery.setType(Query.QueryType.BULK_UPDATE);
} else if (type == QueryType.BULK_DELETE) {
internalQuery.setType(Query.QueryType.BULK_DELETE);
}
QueryCompilation compilation = getCompilation();
internalQuery.setCompilation(compilation);
return internalQuery;
}
use of org.datanucleus.query.compiler.QueryCompilation in project datanucleus-api-jdo by datanucleus.
the class AbstractJDOQLTypedQuery method compile.
/**
* Method to compile the query as it is currently defined.
* @param mmgr Metadata manager
* @param clr ClassLoader resolver
* @return The generic compilation
*/
protected QueryCompilation compile(MetaDataManager mmgr, ClassLoaderResolver clr) {
SymbolTable symtbl = new SymbolTable();
symtbl.setSymbolResolver(new JDOQLSymbolResolver(mmgr, clr, symtbl, candidateCls, candidateAlias));
symtbl.addSymbol(new PropertySymbol(candidateAlias, candidateCls));
org.datanucleus.query.expression.Expression[] resultExprs = null;
if (result != null && !result.isEmpty()) {
resultExprs = new org.datanucleus.query.expression.Expression[result.size()];
Iterator iter = result.iterator();
int i = 0;
while (iter.hasNext()) {
ExpressionImpl result = (ExpressionImpl) iter.next();
org.datanucleus.query.expression.Expression resultExpr = result.getQueryExpression();
resultExpr.bind(symtbl);
resultExprs[i++] = resultExpr;
}
if (resultExprs.length == 1 && resultExprs[0] instanceof PrimaryExpression) {
// Check for special case of "Object(p)" in result, which means no special result
String resultExprId = ((PrimaryExpression) resultExprs[0]).getId();
if (resultExprId.equalsIgnoreCase(candidateAlias)) {
resultExprs = null;
}
}
}
org.datanucleus.query.expression.Expression filterExpr = null;
if (filter != null) {
filterExpr = filter.getQueryExpression();
if (filterExpr != null) {
filterExpr.bind(symtbl);
}
}
org.datanucleus.query.expression.Expression[] groupingExprs = null;
if (grouping != null && !grouping.isEmpty()) {
groupingExprs = new org.datanucleus.query.expression.Expression[grouping.size()];
Iterator iter = grouping.iterator();
int i = 0;
while (iter.hasNext()) {
ExpressionImpl grp = (ExpressionImpl) iter.next();
org.datanucleus.query.expression.Expression groupingExpr = grp.getQueryExpression();
groupingExpr.bind(symtbl);
groupingExprs[i++] = groupingExpr;
}
}
org.datanucleus.query.expression.Expression havingExpr = null;
if (having != null) {
havingExpr = having.getQueryExpression();
havingExpr.bind(symtbl);
}
org.datanucleus.query.expression.Expression[] orderExprs = null;
if (ordering != null && !ordering.isEmpty()) {
orderExprs = new org.datanucleus.query.expression.Expression[ordering.size()];
Iterator<OrderExpressionImpl> iter = ordering.iterator();
int i = 0;
while (iter.hasNext()) {
OrderExpressionImpl order = iter.next();
org.datanucleus.query.expression.OrderExpression orderExpr = new org.datanucleus.query.expression.OrderExpression(((ExpressionImpl) order.getExpression()).getQueryExpression(), order.getDirection() == OrderDirection.ASC ? "ascending" : "descending");
orderExpr.bind(symtbl);
orderExprs[i++] = orderExpr;
}
}
org.datanucleus.query.expression.Expression[] updateExprs = null;
if (this.updateExprs != null) {
Iterator<ExpressionImpl> expIter = this.updateExprs.iterator();
Iterator<ExpressionImpl> valIter = this.updateVals.iterator();
updateExprs = new Expression[this.updateExprs.size()];
int i = 0;
while (expIter.hasNext()) {
ExpressionImpl updateExpr = expIter.next();
ExpressionImpl updateVal = valIter.next();
updateExprs[i++] = new DyadicExpression(updateExpr.getQueryExpression(), Expression.OP_EQ, updateVal.getQueryExpression());
}
}
compilation = new QueryCompilation(candidateCls, candidateAlias, symtbl, resultExprs, null, filterExpr, groupingExprs, havingExpr, orderExprs, updateExprs);
compilation.setQueryLanguage(Query.LANGUAGE_JDOQL);
return compilation;
}
use of org.datanucleus.query.compiler.QueryCompilation in project datanucleus-core by datanucleus.
the class JavaQueryInMemoryEvaluator method execute.
/**
* Method to perform the evaluation, applying the query restrictions that are required.
* @param applyFilter Whether to apply any filter constraints on the results
* @param applyOrdering Whether to apply any order constraints on the results
* @param applyResult Whether to apply any result/grouping/having on the results
* @param applyResultClass Whether to apply any resultClass constraint on the results
* @param applyRange Whether to apply any range constraint on the results
* @return The results after evaluation.
*/
public Collection execute(boolean applyFilter, boolean applyOrdering, boolean applyResult, boolean applyResultClass, boolean applyRange) {
if (!applyFilter && !applyOrdering && !applyResult && !applyResultClass && !applyRange) {
// Nothing to evaluate in-memory
return candidates;
}
Collection executeCandidates = new ArrayList();
Expression[] result = compilation.getExprResult();
if (candidates != null) {
if (applyResult && result != null && result.length > 1) {
// Have result but not returning rows of candidate type so remove dupd candidates
Iterator candIter = candidates.iterator();
while (candIter.hasNext()) {
Object candidate = candIter.next();
if (!executeCandidates.contains(candidate)) {
executeCandidates.add(candidate);
}
}
} else {
executeCandidates.addAll(candidates);
}
}
// Really we should aim to have the following order of execution of the different components : FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY
// TODO Retain variables across the different parts of the query. Currently evaluated in filter then forgotten
// TODO Where the subquery makes use of the parent query candidate, set the candidates for the subquery using that. This currently just passes the same parent candidates in!
String[] subqueryAliases = compilation.getSubqueryAliases();
if (subqueryAliases != null) {
for (int i = 0; i < subqueryAliases.length; i++) {
// Evaluate subquery first
Query subquery = query.getSubqueryForVariable(subqueryAliases[i]).getQuery();
QueryCompilation subqueryCompilation = compilation.getCompilationForSubquery(subqueryAliases[i]);
if (subqueryCompilation.getExprFrom() != null) {
// TODO Evaluate "from"
NucleusLogger.QUERY.warn("In-memory evaluation of subquery with 'from'=" + StringUtils.objectArrayToString(subqueryCompilation.getExprFrom()) + " but from clause evaluation not currently supported!");
}
Collection subqueryResult = evaluateSubquery(subquery, subqueryCompilation, executeCandidates, null);
if (QueryUtils.queryReturnsSingleRow(subquery)) {
// Subquery is expected to return single value
state.put(subqueryAliases[i], subqueryResult.iterator().next());
} else {
state.put(subqueryAliases[i], subqueryResult);
}
}
}
// Evaluate filter
List resultSet = new ArrayList(executeCandidates);
Expression filter = compilation.getExprFilter();
if (applyFilter && filter != null) {
// Process any filter constraints
if (NucleusLogger.QUERY.isDebugEnabled()) {
NucleusLogger.QUERY.debug(Localiser.msg("021012", "filter", language, filter));
}
resultSet = handleFilter(resultSet);
}
Expression[] ordering = compilation.getExprOrdering();
if (applyOrdering && ordering != null) {
// Process any ordering constraints
if (NucleusLogger.QUERY.isDebugEnabled()) {
NucleusLogger.QUERY.debug(Localiser.msg("021012", "ordering", language, StringUtils.objectArrayToString(ordering)));
}
resultSet = ordering(resultSet);
}
if (applyRange && query.getRange() != null) {
// Process any range constraints
long fromIncl = query.getRangeFromIncl();
long toExcl = query.getRangeToExcl();
if (query.getRangeFromInclParam() != null) {
fromIncl = ((Number) parameterValues.get(query.getRangeFromInclParam())).longValue();
}
if (query.getRangeToExclParam() != null) {
toExcl = ((Number) parameterValues.get(query.getRangeToExclParam())).longValue();
}
if (NucleusLogger.QUERY.isDebugEnabled()) {
NucleusLogger.QUERY.debug(Localiser.msg("021012", "range", language, "" + fromIncl + "," + toExcl));
}
resultSet = handleRange(resultSet, fromIncl, toExcl);
}
if (applyResult && result != null) {
// Process any result/grouping/having constraints
if (NucleusLogger.QUERY.isDebugEnabled()) {
NucleusLogger.QUERY.debug(Localiser.msg("021012", "result", language, StringUtils.objectArrayToString(result)));
}
// Apply grouping
List aggregateList = new ArrayList();
List s = resultSet;
Expression[] grouping = compilation.getExprGrouping();
if (grouping != null) {
s = sortByGrouping(resultSet);
}
aggregateList = s;
// TODO Move this to within sortByGrouping
if (grouping != null) {
aggregateList = handleAggregates(s);
}
resultSet = handleResult(aggregateList);
if (query.getResultDistinct()) {
List tmpList = new ArrayList();
Iterator iter = resultSet.iterator();
while (iter.hasNext()) {
Object obj = iter.next();
if (// Omit dups
!tmpList.contains(obj)) {
tmpList.add(obj);
}
}
resultSet = tmpList;
}
}
if (applyResultClass && query.getResultClass() != null) {
// Process any result class constraints
if (NucleusLogger.QUERY.isDebugEnabled()) {
NucleusLogger.QUERY.debug(Localiser.msg("021012", "resultClass", language, query.getResultClass().getName()));
}
if (result != null && !(result[0] instanceof CreatorExpression)) {
return this.mapResultClass(resultSet);
}
}
return resultSet;
}
Aggregations