Search in sources :

Example 1 with JDOQLParser

use of org.datanucleus.query.compiler.JDOQLParser 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

NucleusUserException (org.datanucleus.exceptions.NucleusUserException)1 JDOQLParser (org.datanucleus.query.compiler.JDOQLParser)1 DyadicExpression (org.datanucleus.query.expression.DyadicExpression)1 Expression (org.datanucleus.query.expression.Expression)1 InvokeExpression (org.datanucleus.query.expression.InvokeExpression)1 OrderExpression (org.datanucleus.query.expression.OrderExpression)1 ParameterExpression (org.datanucleus.query.expression.ParameterExpression)1 PrimaryExpression (org.datanucleus.query.expression.PrimaryExpression)1 VariableExpression (org.datanucleus.query.expression.VariableExpression)1