use of org.datanucleus.exceptions.NucleusUserException 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.exceptions.NucleusUserException 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.exceptions.NucleusUserException 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.exceptions.NucleusUserException in project datanucleus-core by datanucleus.
the class JPQLParser method processUnaryExpression.
protected void processUnaryExpression() {
if (lexer.parseString("++")) {
throw new NucleusUserException("Unsupported operator '++'");
} else if (lexer.parseString("--")) {
throw new NucleusUserException("Unsupported operator '--'");
}
if (lexer.parseChar('+')) {
// Just swallow + and leave remains on the stack
processUnaryExpression();
} else if (lexer.parseChar('-')) {
processUnaryExpression();
Node expr = new Node(NodeType.OPERATOR, "-");
expr.insertChildNode(stack.pop());
stack.push(expr);
} else if (lexer.parseStringIgnoreCase("NOT ")) {
processRelationalExpression();
Node expr = new Node(NodeType.OPERATOR, "!");
expr.insertChildNode(stack.pop());
stack.push(expr);
} else {
processPrimary();
}
}
use of org.datanucleus.exceptions.NucleusUserException in project datanucleus-core by datanucleus.
the class JavaQueryCompiler method compileFrom.
/**
* Method to compile the "from" clause (if present for the query language).
* @return The compiled from expression(s)
*/
protected Expression[] compileFrom() {
if (from == null) {
return null;
}
Node[] node = parser.parseFrom(from);
Expression[] expr = new Expression[node.length];
for (int i = 0; i < node.length; i++) {
String className = (String) node[i].getNodeValue();
String classAlias = null;
Class cls = null;
if (parentCompiler != null) {
cls = getClassForSubqueryClassExpression(className);
} else {
cls = resolveClass(className);
}
List<Node> children = node[i].getChildNodes();
for (Node child : children) {
if (// Alias - maybe should assume it is the first child
child.getNodeType() == NodeType.NAME) {
classAlias = (String) child.getNodeValue();
}
}
if (i == 0 && classAlias == null) {
throw new QueryCompilerSyntaxException("FROM clause of query has class " + cls.getName() + " but no alias");
}
if (classAlias != null) {
if (i == 0) {
// First expression so set up candidateClass/alias
candidateClass = cls;
if (parentCompiler != null && parentCompiler.candidateAlias.equals(classAlias)) {
// The defined alias is the same as the parent query, so rename
candidateAliasOrig = classAlias;
candidateAlias = "sub_" + candidateAlias;
classAlias = candidateAlias;
swapCandidateAliasNodeName(node[i].getChildNode(0));
} else {
candidateAlias = classAlias;
}
}
if (symtbl.getSymbol(classAlias) == null) {
// Add symbol for this candidate under its alias
symtbl.addSymbol(new PropertySymbol(classAlias, cls));
}
}
for (Node childNode : children) {
// Add entries in symbol table for any joined aliases
if (childNode.getNodeType() == NodeType.OPERATOR) {
Node joinedNode = childNode.getFirstChild();
// Extract alias node
Node aliasNode = childNode.getNextChild();
// Extract ON node (if present)
Node onExprNode = null;
if (childNode.hasNextChild()) {
onExprNode = childNode.getNextChild();
}
String joinedAlias = (String) joinedNode.getNodeValue();
boolean rootNode = false;
Symbol joinedSym = caseSensitiveAliases ? symtbl.getSymbol(joinedAlias) : symtbl.getSymbolIgnoreCase(joinedAlias);
if (joinedSym == null) {
// DN Extension : Check for FROM clause including join to a new root
if (aliasNode != null) {
joinedAlias = (String) aliasNode.getNodeValue();
cls = resolveClass((String) joinedNode.getNodeValue());
if (symtbl.getSymbol(joinedAlias) == null) {
// Add symbol for this candidate under its alias
symtbl.addSymbol(new PropertySymbol(joinedAlias, cls));
rootNode = true;
NucleusLogger.QUERY.debug("Found suspected ROOT node joined to in FROM clause : attempting to process as alias=" + joinedAlias);
}
joinedSym = caseSensitiveAliases ? symtbl.getSymbol(joinedAlias) : symtbl.getSymbolIgnoreCase(joinedAlias);
}
if (joinedSym == null) {
throw new QueryCompilerSyntaxException("FROM clause has identifier " + joinedNode.getNodeValue() + " but this is unknown");
}
}
if (!rootNode) {
AbstractClassMetaData joinedCmd = metaDataManager.getMetaDataForClass(joinedSym.getValueType(), clr);
Class joinedCls = joinedSym.getValueType();
AbstractMemberMetaData joinedMmd = null;
while (joinedNode.getFirstChild() != null) {
joinedNode = joinedNode.getFirstChild();
String joinedMember = (String) joinedNode.getNodeValue();
if (joinedNode.getNodeType() == NodeType.CAST) {
// JOIN to "TREAT(identifier AS subcls)"
String castTypeName = (String) joinedNode.getNodeValue();
if (castTypeName.indexOf('.') < 0) {
// Fully-qualify with the current class name?
castTypeName = ClassUtils.createFullClassName(joinedCmd.getPackageName(), castTypeName);
}
joinedCls = clr.classForName(castTypeName);
// Update cast type now that we have resolved it
joinedNode.setNodeValue(castTypeName);
} else {
// Allow for multi-field joins
String[] joinedMembers = joinedMember.contains(".") ? StringUtils.split(joinedMember, ".") : new String[] { joinedMember };
for (int k = 0; k < joinedMembers.length; k++) {
String memberName = joinedMembers[k];
if (joinedCmd == null) {
throw new NucleusUserException("Query has JOIN to " + memberName + " but previous element (" + joinedCls.getName() + ") has no metadata");
}
if (memberName.endsWith("#KEY")) {
memberName = memberName.substring(0, memberName.length() - 4);
} else if (memberName.endsWith("#VALUE")) {
memberName = memberName.substring(0, memberName.length() - 6);
}
AbstractMemberMetaData mmd = joinedCmd.getMetaDataForMember(memberName);
if (mmd == null) {
if (childNode.getNodeValue().equals(JOIN_OUTER) || childNode.getNodeValue().equals(JOIN_OUTER_FETCH)) {
// Polymorphic join, where the field exists in a subclass (doable since we have outer join)
String[] subclasses = metaDataManager.getSubclassesForClass(joinedCmd.getFullClassName(), true);
if (subclasses != null) {
for (int l = 0; l < subclasses.length; l++) {
AbstractClassMetaData subCmd = metaDataManager.getMetaDataForClass(subclasses[l], clr);
if (subCmd != null) {
mmd = subCmd.getMetaDataForMember(memberName);
if (mmd != null) {
NucleusLogger.QUERY.debug("Polymorphic join found at " + memberName + " of " + subCmd.getFullClassName());
joinedCmd = subCmd;
break;
}
}
}
}
}
if (mmd == null) {
throw new QueryCompilerSyntaxException("FROM clause has reference to " + joinedCmd.getFullClassName() + "." + joinedMembers[k] + " but it doesn't exist!");
}
}
RelationType relationType = mmd.getRelationType(clr);
joinedMmd = mmd;
if (RelationType.isRelationSingleValued(relationType)) {
joinedCls = mmd.getType();
joinedCmd = metaDataManager.getMetaDataForClass(joinedCls, clr);
} else if (RelationType.isRelationMultiValued(relationType)) {
if (mmd.hasCollection()) {
// TODO Don't currently allow interface field navigation
joinedCmd = mmd.getCollection().getElementClassMetaData(clr);
if (joinedCmd != null) {
joinedCls = clr.classForName(joinedCmd.getFullClassName());
} else {
joinedCls = clr.classForName(mmd.getCollection().getElementType());
}
} else if (mmd.hasMap()) {
if (joinedMembers[k].endsWith("#KEY")) {
joinedCmd = mmd.getMap().getKeyClassMetaData(clr);
// TODO Set joinedCls
} else {
joinedCmd = mmd.getMap().getValueClassMetaData(clr);
if (joinedCmd != null) {
// JPA assumption that the value is an entity ... but it may not be!
joinedCls = clr.classForName(joinedCmd.getFullClassName());
} else {
joinedCls = clr.classForName(mmd.getMap().getValueType());
}
}
} else if (mmd.hasArray()) {
// TODO Don't currently allow interface field navigation
joinedCmd = mmd.getArray().getElementClassMetaData(clr);
if (joinedCmd != null) {
joinedCls = clr.classForName(joinedCmd.getFullClassName());
} else {
joinedCls = clr.classForName(mmd.getArray().getElementType());
}
}
}
}
}
}
if (aliasNode != null && aliasNode.getNodeType() == NodeType.NAME) {
// Add JOIN alias to symbol table
String alias = (String) aliasNode.getNodeValue();
symtbl.addSymbol(new PropertySymbol(alias, joinedCls));
if (joinedMmd != null && joinedMmd.hasMap()) {
Class keyCls = clr.classForName(joinedMmd.getMap().getKeyType());
// Add the KEY so that we can have joins to the key from the value alias
symtbl.addSymbol(new PropertySymbol(alias + "#KEY", keyCls));
Class valueCls = clr.classForName(joinedMmd.getMap().getValueType());
// Add the VALUE so that we can have joins to the value from the key alias
symtbl.addSymbol(new PropertySymbol(alias + "#VALUE", valueCls));
}
}
}
if (onExprNode != null) {
// ON condition
ExpressionCompiler comp = new ExpressionCompiler();
comp.setSymbolTable(symtbl);
comp.setMethodAliases(queryMgr.getQueryMethodAliasesByPrefix());
Expression nextExpr = comp.compileExpression(onExprNode);
nextExpr.bind(symtbl);
}
}
}
boolean classIsExpression = false;
String[] tokens = StringUtils.split(className, ".");
if (symtbl.getParentSymbolTable() != null) {
if (symtbl.getParentSymbolTable().hasSymbol(tokens[0])) {
classIsExpression = true;
}
}
ExpressionCompiler comp = new ExpressionCompiler();
comp.setSymbolTable(symtbl);
comp.setMethodAliases(queryMgr.getQueryMethodAliasesByPrefix());
expr[i] = comp.compileFromExpression(node[i], classIsExpression);
if (expr[i] != null) {
expr[i].bind(symtbl);
}
}
return expr;
}
Aggregations