Search in sources :

Example 91 with NucleusUserException

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());
    }
}
Also used : LocalDateTime(java.time.LocalDateTime) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Calendar(java.util.Calendar) NucleusException(org.datanucleus.exceptions.NucleusException) LocalDate(java.time.LocalDate) Date(java.util.Date) LocalDate(java.time.LocalDate)

Example 92 with NucleusUserException

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());
    }
}
Also used : LocalDateTime(java.time.LocalDateTime) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Calendar(java.util.Calendar) NucleusException(org.datanucleus.exceptions.NucleusException) LocalDate(java.time.LocalDate) Date(java.util.Date) LocalDate(java.time.LocalDate)

Example 93 with NucleusUserException

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;
}
Also used : InvokeExpression(org.datanucleus.query.expression.InvokeExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression)

Example 94 with NucleusUserException

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();
    }
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException)

Example 95 with NucleusUserException

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;
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) ParameterExpression(org.datanucleus.query.expression.ParameterExpression) Expression(org.datanucleus.query.expression.Expression) VariableExpression(org.datanucleus.query.expression.VariableExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) QueryCompilerSyntaxException(org.datanucleus.store.query.QueryCompilerSyntaxException) RelationType(org.datanucleus.metadata.RelationType) ExpressionCompiler(org.datanucleus.query.expression.ExpressionCompiler) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

NucleusUserException (org.datanucleus.exceptions.NucleusUserException)258 NucleusException (org.datanucleus.exceptions.NucleusException)65 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)51 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)46 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)46 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)41 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)36 ArrayList (java.util.ArrayList)34 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)30 ObjectProvider (org.datanucleus.state.ObjectProvider)30 ClassNotResolvedException (org.datanucleus.exceptions.ClassNotResolvedException)26 Expression (org.datanucleus.query.expression.Expression)24 InvokeExpression (org.datanucleus.query.expression.InvokeExpression)23 SQLException (java.sql.SQLException)22 PersistableMapping (org.datanucleus.store.rdbms.mapping.java.PersistableMapping)21 NullLiteral (org.datanucleus.store.rdbms.sql.expression.NullLiteral)21 SQLLiteral (org.datanucleus.store.rdbms.sql.expression.SQLLiteral)21 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)20 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)20 BigInteger (java.math.BigInteger)19