Search in sources :

Example 16 with InvokeExpression

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());
    }
}
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 17 with InvokeExpression

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());
    }
}
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 18 with InvokeExpression

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;
}
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 19 with InvokeExpression

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;
}
Also used : InvokeExpression(org.datanucleus.query.expression.InvokeExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression) ParameterExpression(org.datanucleus.query.expression.ParameterExpression) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) VariableExpression(org.datanucleus.query.expression.VariableExpression) OrderExpression(org.datanucleus.query.expression.OrderExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) Literal(org.datanucleus.query.expression.Literal) ParameterExpression(org.datanucleus.query.expression.ParameterExpression) VariableExpression(org.datanucleus.query.expression.VariableExpression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression)

Example 20 with InvokeExpression

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

Aggregations

InvokeExpression (org.datanucleus.query.expression.InvokeExpression)65 Literal (org.datanucleus.query.expression.Literal)42 DyadicExpression (org.datanucleus.query.expression.DyadicExpression)40 Expression (org.datanucleus.query.expression.Expression)39 PrimaryExpression (org.datanucleus.query.expression.PrimaryExpression)38 ParameterExpression (org.datanucleus.query.expression.ParameterExpression)37 NucleusException (org.datanucleus.exceptions.NucleusException)32 ArrayList (java.util.ArrayList)25 VariableExpression (org.datanucleus.query.expression.VariableExpression)21 BooleanExpression (javax.jdo.query.BooleanExpression)17 NumericExpression (javax.jdo.query.NumericExpression)17 PersistableExpression (javax.jdo.query.PersistableExpression)17 Expression (javax.jdo.query.Expression)15 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)13 OrderExpression (org.datanucleus.query.expression.OrderExpression)12 List (java.util.List)10 CharacterExpression (javax.jdo.query.CharacterExpression)10 StringExpression (javax.jdo.query.StringExpression)10 LocalDateTime (java.time.LocalDateTime)7 Calendar (java.util.Calendar)7