use of org.datanucleus.query.expression.Expression in project datanucleus-core by datanucleus.
the class TemporalHourMethod method evaluate.
/* (non-Javadoc)
* @see org.datanucleus.query.evaluator.memory.InvocationEvaluator#evaluate(org.datanucleus.query.expression.InvokeExpression, org.datanucleus.query.evaluator.memory.InMemoryExpressionEvaluator)
*/
public Object evaluate(InvokeExpression expr, Object invokedValue, InMemoryExpressionEvaluator eval) {
if (invokedValue == null && expr.getArguments() != null) {
// Specified as static function, so use argument of InvokeExpression
List<Expression> argExprs = expr.getArguments();
if (argExprs.size() > 1) {
throw new NucleusUserException("Incorrect number of arguments to HOUR");
}
Expression argExpr = argExprs.get(0);
invokedValue = eval.getValueForExpression(argExpr);
}
if (invokedValue == null) {
return Boolean.FALSE;
}
if (!(invokedValue instanceof Date)) {
throw new NucleusException(Localiser.msg("021011", expr.getOperation(), invokedValue.getClass().getName()));
}
if (invokedValue instanceof Date) {
Calendar cal = Calendar.getInstance();
cal.setTime((Date) invokedValue);
return Integer.valueOf(cal.get(Calendar.HOUR_OF_DAY));
} else if (invokedValue instanceof Calendar) {
return Integer.valueOf(((Calendar) invokedValue).get(Calendar.HOUR_OF_DAY));
} else if (invokedValue instanceof LocalTime) {
return ((LocalTime) invokedValue).getHour();
} else if (invokedValue instanceof LocalDateTime) {
return ((LocalDateTime) invokedValue).getHour();
} else {
throw new NucleusUserException("We do not currently support HOUR() with argument of type " + invokedValue.getClass().getName());
}
}
use of org.datanucleus.query.expression.Expression in project datanucleus-core by datanucleus.
the class TemporalMinuteMethod method evaluate.
/* (non-Javadoc)
* @see org.datanucleus.query.evaluator.memory.InvocationEvaluator#evaluate(org.datanucleus.query.expression.InvokeExpression, org.datanucleus.query.evaluator.memory.InMemoryExpressionEvaluator)
*/
public Object evaluate(InvokeExpression expr, Object invokedValue, InMemoryExpressionEvaluator eval) {
if (invokedValue == null && expr.getArguments() != null) {
// Specified as static function, so use argument of InvokeExpression
List<Expression> argExprs = expr.getArguments();
if (argExprs.size() > 1) {
throw new NucleusUserException("Incorrect number of arguments to MINUTE");
}
Expression argExpr = argExprs.get(0);
invokedValue = eval.getValueForExpression(argExpr);
}
if (invokedValue == null) {
return Boolean.FALSE;
}
if (!(invokedValue instanceof Date)) {
throw new NucleusException(Localiser.msg("021011", expr.getOperation(), invokedValue.getClass().getName()));
}
if (invokedValue instanceof Date) {
Calendar cal = Calendar.getInstance();
cal.setTime((Date) invokedValue);
return Integer.valueOf(cal.get(Calendar.MINUTE));
} else if (invokedValue instanceof Calendar) {
return Integer.valueOf(((Calendar) invokedValue).get(Calendar.MINUTE));
} else if (invokedValue instanceof LocalTime) {
return ((LocalTime) invokedValue).getMinute();
} else if (invokedValue instanceof LocalDateTime) {
return ((LocalDateTime) invokedValue).getMinute();
} else {
throw new NucleusUserException("We do not currently support MINUTE() with argument of type " + invokedValue.getClass().getName());
}
}
use of org.datanucleus.query.expression.Expression in project datanucleus-core by datanucleus.
the class JavaQueryInMemoryEvaluator method satisfiesHavingClause.
/**
* Checks if the results set fulfils the having clause.
* @param set Set of results
* @return true if fulfilling having clause
*/
private boolean satisfiesHavingClause(List set) {
state.put(RESULTS_SET, set);
Expression having = compilation.getExprHaving();
if (having.evaluate(evaluator) == Boolean.TRUE) {
return true;
}
return false;
}
use of org.datanucleus.query.expression.Expression in project datanucleus-core by datanucleus.
the class JavaQueryInMemoryEvaluator method handleFilter.
private List handleFilter(List set) {
Expression filter = compilation.getExprFilter();
if (filter == null) {
return set;
}
// Store current results in case we have an aggregate in the filter
state.put(RESULTS_SET, set);
List result = new ArrayList();
Iterator it = set.iterator();
if (NucleusLogger.QUERY.isDebugEnabled()) {
NucleusLogger.QUERY.debug("Evaluating filter for " + set.size() + " candidates");
}
// TODO Need to use variables from each valid result for the other parts of the query
while (it.hasNext()) {
// Set the value of the candidate being tested, and evaluate it
Object obj = it.next();
if (!state.containsKey(candidateAlias)) {
throw new NucleusUserException("Alias \"" + candidateAlias + "\" doesn't exist in the query or the candidate alias wasn't defined");
}
state.put(candidateAlias, obj);
InMemoryExpressionEvaluator eval = new InMemoryExpressionEvaluator(query.getExecutionContext(), parameterValues, state, query.getParsedImports(), clr, candidateAlias, query.getLanguage());
Object evalResult = evaluateBooleanExpression(filter, eval);
if (Boolean.TRUE.equals(evalResult)) {
if (NucleusLogger.QUERY.isDebugEnabled()) {
NucleusLogger.QUERY.debug(Localiser.msg("021023", StringUtils.toJVMIDString(obj)));
}
result.add(obj);
}
}
return result;
}
use of org.datanucleus.query.expression.Expression 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