use of org.datanucleus.query.expression.InvokeExpression in project datanucleus-core by datanucleus.
the class TemporalMonthMethod 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 MONTH");
}
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.MONTH)) + 1;
} else if (invokedValue instanceof Calendar) {
return Integer.valueOf(((Calendar) invokedValue).get(Calendar.MONTH)) + 1;
} else if (invokedValue instanceof LocalDate) {
return ((LocalDate) invokedValue).getMonthValue();
} else if (invokedValue instanceof LocalDateTime) {
return ((LocalDateTime) invokedValue).getMonthValue();
} else {
throw new NucleusUserException("We do not currently support MONTH() with argument of type " + invokedValue.getClass().getName());
}
}
use of org.datanucleus.query.expression.InvokeExpression in project datanucleus-core by datanucleus.
the class TemporalYearMethod 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 YEAR");
}
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.YEAR));
} else if (invokedValue instanceof Calendar) {
return Integer.valueOf(((Calendar) invokedValue).get(Calendar.YEAR));
} else if (invokedValue instanceof LocalDate) {
return ((LocalDate) invokedValue).getYear();
} else if (invokedValue instanceof LocalDateTime) {
return ((LocalDateTime) invokedValue).getYear();
} else {
throw new NucleusUserException("We do not currently support YEAR() with argument of type " + invokedValue.getClass().getName());
}
}
use of org.datanucleus.query.expression.InvokeExpression in project datanucleus-core by datanucleus.
the class JPQLCompiler method compile.
/**
* Method to compile the query, and return the compiled results.
* @param parameters the parameter map of values keyed by param name
* @param subqueryMap Map of subquery variables, keyed by the subquery name
* @return The compiled query
*/
public QueryCompilation compile(Map parameters, Map subqueryMap) {
parser = new JPQLParser();
if (options != null && options.containsKey(Query.EXTENSION_JPQL_STRICT)) {
parser.setStrict(Boolean.parseBoolean((String) options.get(Query.EXTENSION_JPQL_STRICT)));
}
symtbl = new SymbolTable();
symtbl.setSymbolResolver(this);
if (parentCompiler != null) {
symtbl.setParentSymbolTable(parentCompiler.symtbl);
}
if (subqueryMap != null && !subqueryMap.isEmpty()) {
// Load subqueries into symbol table so the compilation knows about them
Iterator<String> subqueryIter = subqueryMap.keySet().iterator();
while (subqueryIter.hasNext()) {
String subqueryName = subqueryIter.next();
Symbol sym = new PropertySymbol(subqueryName);
sym.setType(Symbol.VARIABLE);
symtbl.addSymbol(sym);
}
}
Expression[] exprFrom = compileFrom();
compileCandidatesParametersVariables(parameters);
Expression exprFilter = compileFilter();
Expression[] exprOrdering = compileOrdering();
Expression[] exprResult = compileResult();
Expression[] exprGrouping = compileGrouping();
Expression exprHaving = compileHaving();
Expression[] exprUpdate = compileUpdate();
if (exprResult != null && exprResult.length == 1 && exprResult[0] instanceof PrimaryExpression) {
// Check for special case of "Object(p)" in result, which means no special result
String resultExprId = ((PrimaryExpression) exprResult[0]).getId();
if (resultExprId.equalsIgnoreCase(candidateAlias)) {
exprResult = null;
}
}
if (exprResult != null) {
for (int i = 0; i < exprResult.length; i++) {
if (exprResult[i] instanceof InvokeExpression) {
InvokeExpression invokeExpr = (InvokeExpression) exprResult[i];
if (isMethodNameAggregate(invokeExpr.getOperation())) {
// Make sure these have 1 argument
List<Expression> args = invokeExpr.getArguments();
if (args == null || args.size() != 1) {
throw new NucleusUserException("JPQL query has result clause using aggregate (" + invokeExpr.getOperation() + ") but this needs 1 argument");
}
}
}
}
}
QueryCompilation compilation = new QueryCompilation(candidateClass, candidateAlias, symtbl, exprResult, exprFrom, exprFilter, exprGrouping, exprHaving, exprOrdering, exprUpdate);
compilation.setQueryLanguage(getLanguage());
return compilation;
}
use of org.datanucleus.query.expression.InvokeExpression in project datanucleus-core by datanucleus.
the class JDOQLCompiler method containsOnlyGroupingOrAggregates.
/**
* Convenience method to check the provided expression for whether it contains only grouping expressions
* or aggregates
* @param expr The expression to check
* @param exprGrouping The grouping expressions
* @return Whether it contains only grouping or aggregates
*/
private static boolean containsOnlyGroupingOrAggregates(Expression expr, Expression[] exprGrouping) {
if (expr == null) {
return true;
} else if (expr instanceof DyadicExpression) {
Expression left = expr.getLeft();
Expression right = expr.getRight();
if (!containsOnlyGroupingOrAggregates(left, exprGrouping)) {
return false;
}
if (!containsOnlyGroupingOrAggregates(right, exprGrouping)) {
return false;
}
return true;
} else if (expr instanceof InvokeExpression) {
InvokeExpression invExpr = (InvokeExpression) expr;
if (isExpressionGroupingOrAggregate(invExpr, exprGrouping)) {
return true;
}
Expression invokedExpr = invExpr.getLeft();
if (invokedExpr != null && !containsOnlyGroupingOrAggregates(invokedExpr, exprGrouping)) {
// Check invoked object
return false;
}
List<Expression> invArgs = invExpr.getArguments();
if (invArgs != null) {
// Check invocation arguments
Iterator<Expression> iter = invArgs.iterator();
while (iter.hasNext()) {
Expression argExpr = iter.next();
if (!containsOnlyGroupingOrAggregates(argExpr, exprGrouping)) {
return false;
}
}
}
return true;
} else if (expr instanceof PrimaryExpression) {
return isExpressionGroupingOrAggregate(expr, exprGrouping);
} else if (expr instanceof Literal) {
return true;
} else if (expr instanceof ParameterExpression) {
return true;
} else if (expr instanceof VariableExpression) {
return true;
}
return false;
}
use of org.datanucleus.query.expression.InvokeExpression in project datanucleus-core by datanucleus.
the class JDOQLCompiler method compile.
/**
* Method to compile the query, and return the compiled results.
* @param parameters the parameter map of values keyed by param name
* @param subqueryMap Map of subquery variables, keyed by the subquery name
* @return The compiled query
*/
public QueryCompilation compile(Map parameters, Map subqueryMap) {
parser = new JDOQLParser();
parser.setExplicitParameters(this.parameters != null);
if (options != null && options.containsKey(Query.EXTENSION_JDOQL_STRICT)) {
parser.setStrict(Boolean.parseBoolean((String) options.get(Query.EXTENSION_JDOQL_STRICT)));
}
symtbl = new SymbolTable();
symtbl.setSymbolResolver(this);
if (parentCompiler != null) {
symtbl.setParentSymbolTable(parentCompiler.symtbl);
}
if (subqueryMap != null && !subqueryMap.isEmpty()) {
// Load subqueries into symbol table so the compilation knows about them
Iterator<String> subqueryIter = subqueryMap.keySet().iterator();
while (subqueryIter.hasNext()) {
String subqueryName = subqueryIter.next();
Symbol sym = new PropertySymbol(subqueryName);
sym.setType(Symbol.VARIABLE);
symtbl.addSymbol(sym);
}
}
Expression[] exprFrom = compileFrom();
compileCandidatesParametersVariables(parameters);
Expression exprFilter = compileFilter();
Expression[] exprOrdering = compileOrdering();
Expression[] exprResult = compileResult();
Expression[] exprGrouping = compileGrouping();
Expression exprHaving = compileHaving();
Expression[] exprUpdate = compileUpdate();
// Impose checks from JDO spec
if (exprGrouping != null) {
// - an aggregate expression evaluated once per group.
if (exprResult != null) {
for (int i = 0; i < exprResult.length; i++) {
if (!isExpressionGroupingOrAggregate(exprResult[i], exprGrouping)) {
throw new NucleusUserException(Localiser.msg("021086", exprResult[i]));
}
}
}
// - an aggregate expression evaluated once per group.
if (exprOrdering != null) {
for (int i = 0; i < exprOrdering.length; i++) {
if (!isExpressionGroupingOrAggregate(exprOrdering[i], exprGrouping)) {
throw new NucleusUserException(Localiser.msg("021087", exprOrdering[i]));
}
}
}
}
if (exprHaving != null) {
// grouping expression.
if (!containsOnlyGroupingOrAggregates(exprHaving, exprGrouping)) {
throw new NucleusUserException(Localiser.msg("021088", exprHaving));
}
}
if (exprResult != null) {
for (int i = 0; i < exprResult.length; i++) {
if (exprResult[i] instanceof InvokeExpression) {
InvokeExpression invokeExpr = (InvokeExpression) exprResult[i];
if (isMethodNameAggregate(invokeExpr.getOperation())) {
// Make sure these have 1 argument
List<Expression> args = invokeExpr.getArguments();
if (args == null || args.size() != 1) {
throw new NucleusUserException(Localiser.msg("021089", invokeExpr.getOperation()));
}
}
}
}
}
QueryCompilation compilation = new QueryCompilation(candidateClass, candidateAlias, symtbl, exprResult, exprFrom, exprFilter, exprGrouping, exprHaving, exprOrdering, exprUpdate);
compilation.setQueryLanguage(getLanguage());
// Apply compilation optimisations
if (options != null) {
if (options.containsKey(PropertyNames.PROPERTY_QUERY_COMPILE_OPTIMISE_VAR_THIS)) {
Boolean val = (Boolean) options.get(PropertyNames.PROPERTY_QUERY_COMPILE_OPTIMISE_VAR_THIS);
if (val == Boolean.TRUE) {
// Perform "var == this" optimisation TODO Enable this using a query extension
CompilationOptimiser optimiser = new VarThisCompilationOptimiser(compilation, metaDataManager, clr);
optimiser.optimise();
}
}
// TODO Add handling of relation navigation implying "relation != null". See NavigationNullCompilationOptimiser for a start point
// i.e if we have "this.field1.field2 = val" this is equivalent to "this.field1 != null && this.field1.field2 = val"
}
return compilation;
}
Aggregations