Search in sources :

Example 21 with QueryCompilation

use of org.datanucleus.query.compiler.QueryCompilation in project tests by datanucleus.

the class JDOQLCompilerTest method testFilterImplicitVariable.

/**
 * Test for use of an implicit variable in the filter.
 */
public void testFilterImplicitVariable() {
    // Test use of implicit variable in filter
    JavaQueryCompiler compiler = null;
    QueryCompilation compilation = null;
    try {
        compiler = new JDOQLCompiler(nucCtx, nucCtx.getClassLoaderResolver(null), null, Product.class, null, "notaField == 2", null, null, null, null, null, null, null, null);
        compilation = compiler.compile(null, null);
    } catch (NucleusUserException ne) {
        // TODO Debatable if this should throw a JDOUserException since the "notaField" is not bound, nor typed
        NucleusLogger.QUERY.error("Exception thrown during compilation", ne);
        fail("compilation of filter with valid field threw exception : " + ne.getMessage());
    }
    Expression expr = compilation.getExprFilter();
    assertTrue("Compiled expression should have been DyadicExpression but wasnt", expr instanceof DyadicExpression);
    DyadicExpression dyExpr = (DyadicExpression) expr;
    assertTrue("Compiled left expression should be VariableExpression but isnt", dyExpr.getLeft() instanceof VariableExpression);
    assertTrue("Compiled right expression should be Literal but isnt", dyExpr.getRight() instanceof Literal);
    VariableExpression left = (VariableExpression) dyExpr.getLeft();
    assertEquals("Variable expression name is wrong", left.getId(), "notaField");
    Literal right = (Literal) dyExpr.getRight();
    assertEquals("Literal has wrong value", new Long(2), right.getLiteral());
}
Also used : JDOQLCompiler(org.datanucleus.query.compiler.JDOQLCompiler) JavaQueryCompiler(org.datanucleus.query.compiler.JavaQueryCompiler) 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) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Literal(org.datanucleus.query.expression.Literal) Product(org.datanucleus.samples.store.Product) VariableExpression(org.datanucleus.query.expression.VariableExpression) QueryCompilation(org.datanucleus.query.compiler.QueryCompilation) DyadicExpression(org.datanucleus.query.expression.DyadicExpression)

Example 22 with QueryCompilation

use of org.datanucleus.query.compiler.QueryCompilation in project tests by datanucleus.

the class JDOQLCompilerTest method testFilterWithNegateExpression.

/**
 * Tests for "!(expression)".
 */
public void testFilterWithNegateExpression() {
    JavaQueryCompiler compiler = null;
    QueryCompilation compilation = null;
    try {
        compiler = new JDOQLCompiler(nucCtx, nucCtx.getClassLoaderResolver(null), null, Product.class, null, "!(price > 32)", null, null, null, null, null, null, null, null);
        compilation = compiler.compile(new HashMap(), null);
    } catch (NucleusException ne) {
        NucleusLogger.QUERY.error("Exception thrown during compilation", ne);
        fail("compilation of filter with valid field threw exception : " + ne.getMessage());
    }
    Expression expr = compilation.getExprFilter();
    assertTrue("Compiled expression should have been DyadicExpression but wasnt", expr instanceof DyadicExpression);
    DyadicExpression dyExpr = (DyadicExpression) expr;
    assertTrue("Compiled left expression should have been DyadicExpression but wasnt", dyExpr.getLeft() instanceof DyadicExpression);
    assertNull("Compiled right expression should have been null but wasnt", dyExpr.getRight());
    assertEquals("Expression operator is wrong", Expression.OP_NOT, dyExpr.getOperator());
    DyadicExpression leftExpr = (DyadicExpression) dyExpr.getLeft();
    assertTrue("Left (left) should be PrimaryExpression but isnt", leftExpr.getLeft() instanceof PrimaryExpression);
    assertTrue("Left (right) should be Literal but isnt", leftExpr.getRight() instanceof Literal);
    assertEquals("Left expression operator is wrong", Expression.OP_GT, leftExpr.getOperator());
    PrimaryExpression primExpr = (PrimaryExpression) leftExpr.getLeft();
    assertEquals("Left (left) expression has incorrect number of tuples", 1, primExpr.getTuples().size());
    assertEquals("Left (left) expression 'id' is incorrect", "price", primExpr.getId());
    Literal lit = (Literal) leftExpr.getRight();
    assertTrue("Left (right) expression literal is of incorrect type", lit.getLiteral() instanceof Long);
    assertEquals("Left (right) expression literal has incorrect value", 32, ((Long) lit.getLiteral()).longValue());
}
Also used : JDOQLCompiler(org.datanucleus.query.compiler.JDOQLCompiler) JavaQueryCompiler(org.datanucleus.query.compiler.JavaQueryCompiler) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) HashMap(java.util.HashMap) 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) Product(org.datanucleus.samples.store.Product) QueryCompilation(org.datanucleus.query.compiler.QueryCompilation) NucleusException(org.datanucleus.exceptions.NucleusException) DyadicExpression(org.datanucleus.query.expression.DyadicExpression)

Example 23 with QueryCompilation

use of org.datanucleus.query.compiler.QueryCompilation in project datanucleus-api-jdo by datanucleus.

the class JDOQLTypedQueryImpl method getInternalQuery.

/**
 * Convenience method to generate an internal DataNucleus Query and apply the generic compilation to it.
 * @return The internal DataNucleus query
 */
protected Query getInternalQuery() {
    // Create a DataNucleus query and set the generic compilation
    Query internalQuery = ec.getStoreManager().newQuery(Query.LANGUAGE_JDOQL, ec, toString());
    if (ec.getFlushMode() == FlushMode.QUERY) {
        // Flush mode implies flush all before executing the query so set the necessary property
        internalQuery.addExtension(Query.EXTENSION_FLUSH_BEFORE_EXECUTION, Boolean.TRUE);
    }
    internalQuery.setIgnoreCache(ignoreCache);
    if (extensions != null) {
        internalQuery.setExtensions(extensions);
    }
    if (fetchPlan != null) {
        internalQuery.setFetchPlan(fetchPlan.getInternalFetchPlan());
    }
    if (serializeRead != null) {
        internalQuery.setSerializeRead(serializeRead);
    }
    if (datastoreReadTimeout != null) {
        internalQuery.setDatastoreReadTimeoutMillis(datastoreReadTimeout);
    }
    if (datastoreWriteTimeout != null) {
        internalQuery.setDatastoreWriteTimeoutMillis(datastoreWriteTimeout);
    }
    if (!subclasses) {
        internalQuery.setSubclasses(false);
    }
    if (type == QueryType.SELECT) {
        internalQuery.setType(Query.QueryType.SELECT);
        if (resultDistinct != null) {
            internalQuery.setResultDistinct(resultDistinct.booleanValue());
        }
        internalQuery.setResultClass(resultClass);
        internalQuery.setUnique(unique);
        if (candidates != null) {
            internalQuery.setCandidates(candidates);
        }
    } else if (type == QueryType.BULK_UPDATE) {
        internalQuery.setType(Query.QueryType.BULK_UPDATE);
    } else if (type == QueryType.BULK_DELETE) {
        internalQuery.setType(Query.QueryType.BULK_DELETE);
    }
    QueryCompilation compilation = getCompilation();
    internalQuery.setCompilation(compilation);
    return internalQuery;
}
Also used : Query(org.datanucleus.store.query.Query) JDOQLTypedQuery(javax.jdo.JDOQLTypedQuery) JDOQuery(org.datanucleus.api.jdo.JDOQuery) QueryCompilation(org.datanucleus.query.compiler.QueryCompilation)

Example 24 with QueryCompilation

use of org.datanucleus.query.compiler.QueryCompilation in project datanucleus-api-jdo by datanucleus.

the class AbstractJDOQLTypedQuery method compile.

/**
 * Method to compile the query as it is currently defined.
 * @param mmgr Metadata manager
 * @param clr ClassLoader resolver
 * @return The generic compilation
 */
protected QueryCompilation compile(MetaDataManager mmgr, ClassLoaderResolver clr) {
    SymbolTable symtbl = new SymbolTable();
    symtbl.setSymbolResolver(new JDOQLSymbolResolver(mmgr, clr, symtbl, candidateCls, candidateAlias));
    symtbl.addSymbol(new PropertySymbol(candidateAlias, candidateCls));
    org.datanucleus.query.expression.Expression[] resultExprs = null;
    if (result != null && !result.isEmpty()) {
        resultExprs = new org.datanucleus.query.expression.Expression[result.size()];
        Iterator iter = result.iterator();
        int i = 0;
        while (iter.hasNext()) {
            ExpressionImpl result = (ExpressionImpl) iter.next();
            org.datanucleus.query.expression.Expression resultExpr = result.getQueryExpression();
            resultExpr.bind(symtbl);
            resultExprs[i++] = resultExpr;
        }
        if (resultExprs.length == 1 && resultExprs[0] instanceof PrimaryExpression) {
            // Check for special case of "Object(p)" in result, which means no special result
            String resultExprId = ((PrimaryExpression) resultExprs[0]).getId();
            if (resultExprId.equalsIgnoreCase(candidateAlias)) {
                resultExprs = null;
            }
        }
    }
    org.datanucleus.query.expression.Expression filterExpr = null;
    if (filter != null) {
        filterExpr = filter.getQueryExpression();
        if (filterExpr != null) {
            filterExpr.bind(symtbl);
        }
    }
    org.datanucleus.query.expression.Expression[] groupingExprs = null;
    if (grouping != null && !grouping.isEmpty()) {
        groupingExprs = new org.datanucleus.query.expression.Expression[grouping.size()];
        Iterator iter = grouping.iterator();
        int i = 0;
        while (iter.hasNext()) {
            ExpressionImpl grp = (ExpressionImpl) iter.next();
            org.datanucleus.query.expression.Expression groupingExpr = grp.getQueryExpression();
            groupingExpr.bind(symtbl);
            groupingExprs[i++] = groupingExpr;
        }
    }
    org.datanucleus.query.expression.Expression havingExpr = null;
    if (having != null) {
        havingExpr = having.getQueryExpression();
        havingExpr.bind(symtbl);
    }
    org.datanucleus.query.expression.Expression[] orderExprs = null;
    if (ordering != null && !ordering.isEmpty()) {
        orderExprs = new org.datanucleus.query.expression.Expression[ordering.size()];
        Iterator<OrderExpressionImpl> iter = ordering.iterator();
        int i = 0;
        while (iter.hasNext()) {
            OrderExpressionImpl order = iter.next();
            org.datanucleus.query.expression.OrderExpression orderExpr = new org.datanucleus.query.expression.OrderExpression(((ExpressionImpl) order.getExpression()).getQueryExpression(), order.getDirection() == OrderDirection.ASC ? "ascending" : "descending");
            orderExpr.bind(symtbl);
            orderExprs[i++] = orderExpr;
        }
    }
    org.datanucleus.query.expression.Expression[] updateExprs = null;
    if (this.updateExprs != null) {
        Iterator<ExpressionImpl> expIter = this.updateExprs.iterator();
        Iterator<ExpressionImpl> valIter = this.updateVals.iterator();
        updateExprs = new Expression[this.updateExprs.size()];
        int i = 0;
        while (expIter.hasNext()) {
            ExpressionImpl updateExpr = expIter.next();
            ExpressionImpl updateVal = valIter.next();
            updateExprs[i++] = new DyadicExpression(updateExpr.getQueryExpression(), Expression.OP_EQ, updateVal.getQueryExpression());
        }
    }
    compilation = new QueryCompilation(candidateCls, candidateAlias, symtbl, resultExprs, null, filterExpr, groupingExprs, havingExpr, orderExprs, updateExprs);
    compilation.setQueryLanguage(Query.LANGUAGE_JDOQL);
    return compilation;
}
Also used : PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) PropertySymbol(org.datanucleus.query.compiler.PropertySymbol) Expression(org.datanucleus.query.expression.Expression) SymbolTable(org.datanucleus.query.compiler.SymbolTable) DyadicExpression(org.datanucleus.query.expression.DyadicExpression) 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) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) Iterator(java.util.Iterator) JDOQLSymbolResolver(org.datanucleus.query.compiler.JDOQLSymbolResolver) QueryCompilation(org.datanucleus.query.compiler.QueryCompilation)

Example 25 with QueryCompilation

use of org.datanucleus.query.compiler.QueryCompilation in project datanucleus-core by datanucleus.

the class JavaQueryInMemoryEvaluator method execute.

/**
 * Method to perform the evaluation, applying the query restrictions that are required.
 * @param applyFilter Whether to apply any filter constraints on the results
 * @param applyOrdering Whether to apply any order constraints on the results
 * @param applyResult Whether to apply any result/grouping/having on the results
 * @param applyResultClass Whether to apply any resultClass constraint on the results
 * @param applyRange Whether to apply any range constraint on the results
 * @return The results after evaluation.
 */
public Collection execute(boolean applyFilter, boolean applyOrdering, boolean applyResult, boolean applyResultClass, boolean applyRange) {
    if (!applyFilter && !applyOrdering && !applyResult && !applyResultClass && !applyRange) {
        // Nothing to evaluate in-memory
        return candidates;
    }
    Collection executeCandidates = new ArrayList();
    Expression[] result = compilation.getExprResult();
    if (candidates != null) {
        if (applyResult && result != null && result.length > 1) {
            // Have result but not returning rows of candidate type so remove dupd candidates
            Iterator candIter = candidates.iterator();
            while (candIter.hasNext()) {
                Object candidate = candIter.next();
                if (!executeCandidates.contains(candidate)) {
                    executeCandidates.add(candidate);
                }
            }
        } else {
            executeCandidates.addAll(candidates);
        }
    }
    // Really we should aim to have the following order of execution of the different components : FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY
    // TODO Retain variables across the different parts of the query. Currently evaluated in filter then forgotten
    // TODO Where the subquery makes use of the parent query candidate, set the candidates for the subquery using that. This currently just passes the same parent candidates in!
    String[] subqueryAliases = compilation.getSubqueryAliases();
    if (subqueryAliases != null) {
        for (int i = 0; i < subqueryAliases.length; i++) {
            // Evaluate subquery first
            Query subquery = query.getSubqueryForVariable(subqueryAliases[i]).getQuery();
            QueryCompilation subqueryCompilation = compilation.getCompilationForSubquery(subqueryAliases[i]);
            if (subqueryCompilation.getExprFrom() != null) {
                // TODO Evaluate "from"
                NucleusLogger.QUERY.warn("In-memory evaluation of subquery with 'from'=" + StringUtils.objectArrayToString(subqueryCompilation.getExprFrom()) + " but from clause evaluation not currently supported!");
            }
            Collection subqueryResult = evaluateSubquery(subquery, subqueryCompilation, executeCandidates, null);
            if (QueryUtils.queryReturnsSingleRow(subquery)) {
                // Subquery is expected to return single value
                state.put(subqueryAliases[i], subqueryResult.iterator().next());
            } else {
                state.put(subqueryAliases[i], subqueryResult);
            }
        }
    }
    // Evaluate filter
    List resultSet = new ArrayList(executeCandidates);
    Expression filter = compilation.getExprFilter();
    if (applyFilter && filter != null) {
        // Process any filter constraints
        if (NucleusLogger.QUERY.isDebugEnabled()) {
            NucleusLogger.QUERY.debug(Localiser.msg("021012", "filter", language, filter));
        }
        resultSet = handleFilter(resultSet);
    }
    Expression[] ordering = compilation.getExprOrdering();
    if (applyOrdering && ordering != null) {
        // Process any ordering constraints
        if (NucleusLogger.QUERY.isDebugEnabled()) {
            NucleusLogger.QUERY.debug(Localiser.msg("021012", "ordering", language, StringUtils.objectArrayToString(ordering)));
        }
        resultSet = ordering(resultSet);
    }
    if (applyRange && query.getRange() != null) {
        // Process any range constraints
        long fromIncl = query.getRangeFromIncl();
        long toExcl = query.getRangeToExcl();
        if (query.getRangeFromInclParam() != null) {
            fromIncl = ((Number) parameterValues.get(query.getRangeFromInclParam())).longValue();
        }
        if (query.getRangeToExclParam() != null) {
            toExcl = ((Number) parameterValues.get(query.getRangeToExclParam())).longValue();
        }
        if (NucleusLogger.QUERY.isDebugEnabled()) {
            NucleusLogger.QUERY.debug(Localiser.msg("021012", "range", language, "" + fromIncl + "," + toExcl));
        }
        resultSet = handleRange(resultSet, fromIncl, toExcl);
    }
    if (applyResult && result != null) {
        // Process any result/grouping/having constraints
        if (NucleusLogger.QUERY.isDebugEnabled()) {
            NucleusLogger.QUERY.debug(Localiser.msg("021012", "result", language, StringUtils.objectArrayToString(result)));
        }
        // Apply grouping
        List aggregateList = new ArrayList();
        List s = resultSet;
        Expression[] grouping = compilation.getExprGrouping();
        if (grouping != null) {
            s = sortByGrouping(resultSet);
        }
        aggregateList = s;
        // TODO Move this to within sortByGrouping
        if (grouping != null) {
            aggregateList = handleAggregates(s);
        }
        resultSet = handleResult(aggregateList);
        if (query.getResultDistinct()) {
            List tmpList = new ArrayList();
            Iterator iter = resultSet.iterator();
            while (iter.hasNext()) {
                Object obj = iter.next();
                if (// Omit dups
                !tmpList.contains(obj)) {
                    tmpList.add(obj);
                }
            }
            resultSet = tmpList;
        }
    }
    if (applyResultClass && query.getResultClass() != null) {
        // Process any result class constraints
        if (NucleusLogger.QUERY.isDebugEnabled()) {
            NucleusLogger.QUERY.debug(Localiser.msg("021012", "resultClass", language, query.getResultClass().getName()));
        }
        if (result != null && !(result[0] instanceof CreatorExpression)) {
            return this.mapResultClass(resultSet);
        }
    }
    return resultSet;
}
Also used : Query(org.datanucleus.store.query.Query) ArrayList(java.util.ArrayList) CreatorExpression(org.datanucleus.query.expression.CreatorExpression) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) CreatorExpression(org.datanucleus.query.expression.CreatorExpression) Iterator(java.util.Iterator) Collection(java.util.Collection) ArrayList(java.util.ArrayList) List(java.util.List) QueryCompilation(org.datanucleus.query.compiler.QueryCompilation)

Aggregations

QueryCompilation (org.datanucleus.query.compiler.QueryCompilation)54 JavaQueryCompiler (org.datanucleus.query.compiler.JavaQueryCompiler)44 HashMap (java.util.HashMap)34 JDOQLCompiler (org.datanucleus.query.compiler.JDOQLCompiler)33 Expression (org.datanucleus.query.expression.Expression)28 InvokeExpression (org.datanucleus.query.expression.InvokeExpression)28 DyadicExpression (org.datanucleus.query.expression.DyadicExpression)27 ParameterExpression (org.datanucleus.query.expression.ParameterExpression)27 PrimaryExpression (org.datanucleus.query.expression.PrimaryExpression)27 VariableExpression (org.datanucleus.query.expression.VariableExpression)27 NucleusException (org.datanucleus.exceptions.NucleusException)23 Literal (org.datanucleus.query.expression.Literal)18 List (java.util.List)17 OrderExpression (org.datanucleus.query.expression.OrderExpression)16 Product (org.datanucleus.samples.store.Product)16 Query (org.datanucleus.store.query.Query)16 ArrayList (java.util.ArrayList)15 JDOQuery (org.datanucleus.api.jdo.JDOQuery)15 PersistenceManager (javax.jdo.PersistenceManager)14 Transaction (javax.jdo.Transaction)14