use of org.datanucleus.query.expression.PrimaryExpression 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.PrimaryExpression 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.PrimaryExpression in project datanucleus-core by datanucleus.
the class AbstractResultClassMapper method map.
/**
* Method to map the input results to the required result class type.
* @param inputResults The results to process
* @param resultNames Expressions for the result components of the input results (columns)
* @return Collection<resultClass>
*/
public Collection map(final Collection inputResults, final Expression[] resultNames) {
// Do as PrivilegedAction since can use reflection
return (Collection) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
String[] fieldNames = new String[resultNames.length];
Field[] fields = new Field[fieldNames.length];
for (int i = 0; i < fieldNames.length; i++) {
if (resultNames[i] instanceof PrimaryExpression) {
fieldNames[i] = ((PrimaryExpression) resultNames[i]).getId();
if (fieldNames[i].indexOf('.') > 0) {
// Just take last part of name (for when the user specifies something like "p.firstName")
int pos = fieldNames[i].lastIndexOf('.');
fieldNames[i] = fieldNames[i].substring(pos + 1);
}
fields[i] = getFieldForFieldNameInResultClass(resultClass, fieldNames[i]);
} else if (resultNames[i] instanceof ParameterExpression) {
// TODO We need to cater for outputting the parameter value. Need SymbolTable
// This code below is wrong.
fieldNames[i] = ((ParameterExpression) resultNames[i]).getId();
fields[i] = getFieldForFieldNameInResultClass(resultClass, fieldNames[i]);
} else {
fieldNames[i] = resultNames[i].getAlias();
fields[i] = null;
}
}
List outputResults = new ArrayList();
Iterator it = inputResults.iterator();
while (it.hasNext()) {
Object inputResult = it.next();
Object row = getResultForResultSetRow(inputResult, fieldNames, fields);
outputResults.add(row);
}
return outputResults;
}
});
}
use of org.datanucleus.query.expression.PrimaryExpression in project datanucleus-core by datanucleus.
the class InMemoryExpressionEvaluator method getValueForInvokeExpression.
/**
* Method to evaluate an InvokeExpression.
* Will navigate along chained invocations, evaluating the first one, then the second one etc
* until it gets the value for the passed in expression.
* @param invokeExpr The InvokeExpression
* @return The value
*/
public Object getValueForInvokeExpression(InvokeExpression invokeExpr) {
String method = invokeExpr.getOperation();
if (invokeExpr.getLeft() == null) {
// Static function
if (method.toLowerCase().equals("count")) {
Collection coll = (Collection) state.get(JavaQueryInMemoryEvaluator.RESULTS_SET);
SetExpression setexpr = new SetExpression(coll, candidateAlias);
Expression paramExpr = invokeExpr.getArguments().get(0);
if (paramExpr.getOperator() == Expression.OP_DISTINCT) {
// No dups in HashSet
coll = new HashSet(coll);
}
int stackSizeOrig = stack.size();
Object returnVal = setexpr.count(paramExpr, this);
while (stack.size() > stackSizeOrig) {
// Remove any expressions put on the stack while evaluating the aggregate
stack.pop();
}
return returnVal;
} else if (method.toLowerCase().equals("sum")) {
Collection coll = (Collection) state.get(JavaQueryInMemoryEvaluator.RESULTS_SET);
SetExpression setexpr = new SetExpression(coll, candidateAlias);
Expression paramExpr = invokeExpr.getArguments().get(0);
if (paramExpr.getOperator() == Expression.OP_DISTINCT) {
// No dups in HashSet
coll = new HashSet(coll);
}
int stackSizeOrig = stack.size();
Object returnVal = setexpr.sum(paramExpr, this, state);
while (stack.size() > stackSizeOrig) {
// Remove any expressions put on the stack while evaluating the aggregate
stack.pop();
}
return returnVal;
} else if (method.toLowerCase().equals("avg")) {
Collection coll = (Collection) state.get(JavaQueryInMemoryEvaluator.RESULTS_SET);
SetExpression setexpr = new SetExpression(coll, candidateAlias);
Expression paramExpr = invokeExpr.getArguments().get(0);
if (paramExpr.getOperator() == Expression.OP_DISTINCT) {
// No dups in HashSet
coll = new HashSet(coll);
}
int stackSizeOrig = stack.size();
Object returnVal = setexpr.avg(paramExpr, this, state);
while (stack.size() > stackSizeOrig) {
// Remove any expressions put on the stack while evaluating the aggregate
stack.pop();
}
return returnVal;
} else if (method.toLowerCase().equals("min")) {
Collection coll = (Collection) state.get(JavaQueryInMemoryEvaluator.RESULTS_SET);
SetExpression setexpr = new SetExpression(coll, candidateAlias);
Expression paramExpr = invokeExpr.getArguments().get(0);
if (paramExpr.getOperator() == Expression.OP_DISTINCT) {
// No dups in HashSet
coll = new HashSet(coll);
}
int stackSizeOrig = stack.size();
Object returnVal = setexpr.min(paramExpr, this, state);
while (stack.size() > stackSizeOrig) {
// Remove any expressions put on the stack while evaluating the aggregate
stack.pop();
}
return returnVal;
} else if (method.toLowerCase().equals("max")) {
Collection coll = (Collection) state.get(JavaQueryInMemoryEvaluator.RESULTS_SET);
SetExpression setexpr = new SetExpression(coll, candidateAlias);
Expression paramExpr = invokeExpr.getArguments().get(0);
if (paramExpr.getOperator() == Expression.OP_DISTINCT) {
// No dups in HashSet
coll = new HashSet(coll);
}
int stackSizeOrig = stack.size();
Object returnVal = setexpr.max(paramExpr, this, state);
while (stack.size() > stackSizeOrig) {
// Remove any expressions put on the stack while evaluating the aggregate
stack.pop();
}
return returnVal;
} else {
// Try to find a supported static method with this name
InvocationEvaluator methodEval = queryMgr.getInMemoryEvaluatorForMethod(null, method);
if (methodEval != null) {
return methodEval.evaluate(invokeExpr, null, this);
}
NucleusLogger.QUERY.warn("Query contains call to static method " + method + " yet no support is available for in-memory evaluation of this");
return new InMemoryFailure();
}
} else if (invokeExpr.getLeft() instanceof ParameterExpression) {
// {paramExpr}.method(...)
Object invokedValue = QueryUtils.getValueForParameterExpression(parameterValues, (ParameterExpression) invokeExpr.getLeft());
// Invoke method on this object
Class invokedType = invokedValue != null ? invokedValue.getClass() : invokeExpr.getLeft().getSymbol().getValueType();
InvocationEvaluator methodEval = queryMgr.getInMemoryEvaluatorForMethod(invokedType, method);
if (methodEval != null) {
return methodEval.evaluate(invokeExpr, invokedValue, this);
}
if (invokedValue != null) {
NucleusLogger.QUERY.warn("Query contains call to method " + invokedValue.getClass().getName() + "." + method + " yet no support is available for this");
} else {
NucleusLogger.QUERY.warn("Query contains call to static method " + method + " yet no support is available for this");
}
return new InMemoryFailure();
} else if (invokeExpr.getLeft() instanceof PrimaryExpression) {
// {primaryExpr}.method(...)
Object invokedValue = getValueForPrimaryExpression((PrimaryExpression) invokeExpr.getLeft());
if (invokedValue instanceof InMemoryFailure) {
return invokedValue;
}
// Invoke method on this object
Class invokedType = invokedValue != null ? invokedValue.getClass() : invokeExpr.getLeft().getSymbol().getValueType();
InvocationEvaluator methodEval = queryMgr.getInMemoryEvaluatorForMethod(invokedType, method);
if (methodEval != null) {
return methodEval.evaluate(invokeExpr, invokedValue, this);
}
NucleusLogger.QUERY.warn("Query contains call to method " + invokedType.getName() + "." + method + " yet no support is available for this");
return new InMemoryFailure();
} else if (invokeExpr.getLeft() instanceof InvokeExpression) {
// {invokeExpr}.method(...)
Object invokedValue = getValueForInvokeExpression((InvokeExpression) invokeExpr.getLeft());
// Invoke method on this object
Class invokedType = invokedValue != null ? invokedValue.getClass() : (invokeExpr.getLeft().getSymbol() != null ? invokeExpr.getLeft().getSymbol().getValueType() : null);
if (invokedType == null) {
return new InMemoryFailure();
}
InvocationEvaluator methodEval = queryMgr.getInMemoryEvaluatorForMethod(invokedType, method);
if (methodEval != null) {
return methodEval.evaluate(invokeExpr, invokedValue, this);
}
NucleusLogger.QUERY.warn("Query contains call to method " + invokedType.getName() + "." + method + " yet no support is available for this");
return new InMemoryFailure();
} else if (invokeExpr.getLeft() instanceof VariableExpression) {
// {invokeExpr}.method(...)
Object invokedValue = getValueForVariableExpression((VariableExpression) invokeExpr.getLeft());
// Invoke method on this object
Class invokedType = invokedValue != null ? invokedValue.getClass() : invokeExpr.getLeft().getSymbol().getValueType();
InvocationEvaluator methodEval = queryMgr.getInMemoryEvaluatorForMethod(invokedType, method);
if (methodEval != null) {
return methodEval.evaluate(invokeExpr, invokedValue, this);
}
NucleusLogger.QUERY.warn("Query contains call to method " + invokedType.getName() + "." + method + " yet no support is available for this");
return new InMemoryFailure();
} else if (invokeExpr.getLeft() instanceof Literal) {
// {invokeExpr}.method(...)
Object invokedValue = ((Literal) invokeExpr.getLeft()).getLiteral();
// Invoke method on this object
Class invokedType = invokedValue != null ? invokedValue.getClass() : invokeExpr.getLeft().getSymbol().getValueType();
InvocationEvaluator methodEval = queryMgr.getInMemoryEvaluatorForMethod(invokedType, method);
if (methodEval != null) {
return methodEval.evaluate(invokeExpr, invokedValue, this);
}
NucleusLogger.QUERY.warn("Query contains call to method " + invokedType.getName() + "." + method + " yet no support is available for this");
return new InMemoryFailure();
} else if (invokeExpr.getLeft() instanceof ArrayExpression) {
// {invokeExpr}.method(...)
Object invokedValue = getValueForArrayExpression((ArrayExpression) invokeExpr.getLeft());
// Invoke method on this object
Class invokedType = invokedValue.getClass();
InvocationEvaluator methodEval = queryMgr.getInMemoryEvaluatorForMethod(invokedType, method);
if (methodEval != null) {
return methodEval.evaluate(invokeExpr, invokedValue, this);
}
NucleusLogger.QUERY.warn("Query contains call to method " + invokedType.getName() + "." + method + " yet no support is available for this");
return new InMemoryFailure();
} else {
NucleusLogger.QUERY.warn("No support is available for in-memory evaluation of methods invoked" + " on expressions of type " + invokeExpr.getLeft().getClass().getName());
return new InMemoryFailure();
}
}
use of org.datanucleus.query.expression.PrimaryExpression in project datanucleus-core by datanucleus.
the class JDOQLQueryHelper method getJDOQLForExpression.
public static String getJDOQLForExpression(Expression expr) {
if (expr instanceof DyadicExpression) {
DyadicExpression dyExpr = (DyadicExpression) expr;
Expression left = dyExpr.getLeft();
Expression right = dyExpr.getRight();
StringBuilder str = new StringBuilder("(");
if (dyExpr.getOperator() == Expression.OP_DISTINCT) {
// Distinct goes in front of the left expression
str.append("DISTINCT ");
}
if (left != null) {
str.append(JDOQLQueryHelper.getJDOQLForExpression(left));
}
// Special cases
if (dyExpr.getOperator() == Expression.OP_AND) {
str.append(" && ");
} else if (dyExpr.getOperator() == Expression.OP_OR) {
str.append(" || ");
} else if (dyExpr.getOperator() == Expression.OP_BIT_AND) {
str.append(" & ");
} else if (dyExpr.getOperator() == Expression.OP_BIT_OR) {
str.append(" | ");
} else if (dyExpr.getOperator() == Expression.OP_BIT_XOR) {
str.append(" ^ ");
} else if (dyExpr.getOperator() == Expression.OP_ADD) {
str.append(" + ");
} else if (dyExpr.getOperator() == Expression.OP_SUB) {
str.append(" - ");
} else if (dyExpr.getOperator() == Expression.OP_MUL) {
str.append(" * ");
} else if (dyExpr.getOperator() == Expression.OP_DIV) {
str.append(" / ");
} else if (dyExpr.getOperator() == Expression.OP_EQ) {
str.append(" == ");
} else if (dyExpr.getOperator() == Expression.OP_GT) {
str.append(" > ");
} else if (dyExpr.getOperator() == Expression.OP_LT) {
str.append(" < ");
} else if (dyExpr.getOperator() == Expression.OP_GTEQ) {
str.append(" >= ");
} else if (dyExpr.getOperator() == Expression.OP_LTEQ) {
str.append(" <= ");
} else if (dyExpr.getOperator() == Expression.OP_NOTEQ) {
str.append(" != ");
} else if (dyExpr.getOperator() == Expression.OP_DISTINCT) {
// Processed above
} else {
// TODO Support other operators
throw new UnsupportedOperationException("Dont currently support operator " + dyExpr.getOperator() + " in JDOQL conversion");
}
if (right != null) {
str.append(JDOQLQueryHelper.getJDOQLForExpression(right));
}
str.append(")");
return str.toString();
} else if (expr instanceof PrimaryExpression) {
PrimaryExpression primExpr = (PrimaryExpression) expr;
if (primExpr.getLeft() != null) {
return JDOQLQueryHelper.getJDOQLForExpression(primExpr.getLeft()) + "." + primExpr.getId();
}
return primExpr.getId();
} else if (expr instanceof ParameterExpression) {
ParameterExpression paramExpr = (ParameterExpression) expr;
if (paramExpr.getId() != null) {
return ":" + paramExpr.getId();
}
return "?" + paramExpr.getPosition();
} else if (expr instanceof VariableExpression) {
VariableExpression varExpr = (VariableExpression) expr;
return varExpr.getId();
} else if (expr instanceof InvokeExpression) {
InvokeExpression invExpr = (InvokeExpression) expr;
StringBuilder str = new StringBuilder();
if (invExpr.getLeft() != null) {
str.append(JDOQLQueryHelper.getJDOQLForExpression(invExpr.getLeft())).append(".");
}
str.append(invExpr.getOperation());
str.append("(");
List<Expression> args = invExpr.getArguments();
if (args != null) {
Iterator<Expression> iter = args.iterator();
while (iter.hasNext()) {
str.append(JDOQLQueryHelper.getJDOQLForExpression(iter.next()));
if (iter.hasNext()) {
str.append(",");
}
}
}
str.append(")");
return str.toString();
} else if (expr instanceof Literal) {
Literal litExpr = (Literal) expr;
Object value = litExpr.getLiteral();
if (value instanceof String || value instanceof Character) {
return "'" + value.toString() + "'";
} else if (value instanceof Boolean) {
return (Boolean) value ? "TRUE" : "FALSE";
} else {
if (litExpr.getLiteral() == null) {
return "null";
}
return litExpr.getLiteral().toString();
}
} else {
throw new UnsupportedOperationException("Dont currently support " + expr.getClass().getName() + " in JDOQLHelper");
}
}
Aggregations