Search in sources :

Example 16 with Query

use of org.datanucleus.store.query.Query 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)

Example 17 with Query

use of org.datanucleus.store.query.Query in project datanucleus-core by datanucleus.

the class FederatedQueryManagerImpl method newQuery.

/**
 * Method to generate a new query using the passed query as basis.
 * @param language The query language
 * @param ec ExecutionContext
 * @param query The query filter (String) or a previous Query
 * @return The Query
 */
public Query newQuery(String language, ExecutionContext ec, Object query) {
    if (language == null) {
        return null;
    }
    String languageImpl = language;
    // Find the query support for this language and this datastore
    if (query == null) {
        // TODO We don't have candidate so don't know the StoreManager to use
        throw new NucleusException("Not yet supported for queries with unknown candidate");
    }
    if (query instanceof String) {
        // Single-string query
        String queryString = (String) query;
        String candidateName = null;
        if (languageImpl.equalsIgnoreCase(Query.LANGUAGE_JDOQL) && queryString.toUpperCase().indexOf(" FROM ") > 0) {
            int candidateStart = queryString.toUpperCase().indexOf(" FROM ") + 6;
            int candidateEnd = queryString.indexOf(" ", candidateStart + 1);
            candidateName = queryString.substring(candidateStart, candidateEnd);
        }
        if (candidateName != null) {
            ClassLoaderResolver clr = nucleusCtx.getClassLoaderResolver(null);
            AbstractClassMetaData cmd = nucleusCtx.getMetaDataManager().getMetaDataForClass(candidateName, clr);
            StoreManager classStoreMgr = ((FederatedStoreManager) storeMgr).getStoreManagerForClass(cmd);
            return classStoreMgr.newQuery(languageImpl, ec, (String) query);
        }
        // TODO Find StoreManager for the candidate
        throw new NucleusException("Not yet supported for single-string queries");
    } else if (query instanceof Query) {
        // Based on previous query
        StoreManager storeMgr = ((Query) query).getStoreManager();
        return storeMgr.newQuery(languageImpl, ec, (Query) query);
    } else {
        throw new NucleusException("Not yet supported for queries taking in object of type " + query.getClass());
    }
}
Also used : Query(org.datanucleus.store.query.Query) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) StoreManager(org.datanucleus.store.StoreManager)

Example 18 with Query

use of org.datanucleus.store.query.Query in project tests by datanucleus.

the class JDOQLEvaluatorTest method testFilterMapContainsKeyNonPC.

/**
 * Test of filter with mapField.containsKey(nonPC).
 */
public void testFilterMapContainsKeyNonPC() {
    PersistenceManager pm = pmf.getPersistenceManager();
    Transaction tx = pm.currentTransaction();
    try {
        tx.begin();
        // Create some instances to query over
        List<MapHolder> instances = new ArrayList<>();
        MapHolder holder1 = new MapHolder("First");
        MapHolder holder2 = new MapHolder("Second");
        MapHolder holder3 = new MapHolder("Third");
        holder1.getJoinMapNonNon().put("First", "First Element");
        holder2.getJoinMapNonNon().put("First", "First Element");
        holder2.getJoinMapNonNon().put("Second", "Second Element");
        holder3.getJoinMapNonNon().put("Second", "Second Element");
        holder3.getJoinMapNonNon().put("Third", "Third Element");
        instances.add(holder1);
        instances.add(holder2);
        instances.add(holder3);
        // Compile the query
        JDOQuery q = (JDOQuery) pm.newQuery(MapHolder.class, "joinMapNonNon.containsKey('Third')");
        Query query = q.getInternalQuery();
        ClassLoaderResolver clr = query.getExecutionContext().getClassLoaderResolver();
        JavaQueryCompiler compiler = new JDOQLCompiler(query.getExecutionContext().getNucleusContext(), clr, null, query.getCandidateClass(), null, query.getFilter(), query.getParsedImports(), query.getOrdering(), query.getResult(), query.getGrouping(), query.getHaving(), query.getExplicitParametersDeclaration(), query.getExplicitVariablesDeclaration(), null);
        QueryCompilation compilation = compiler.compile(new HashMap(), null);
        // Execute the query
        JavaQueryInMemoryEvaluator eval = new JDOQLInMemoryEvaluator(query, instances, compilation, null, clr);
        List results = (List) eval.execute(true, true, true, true, true);
        assertEquals("Number of result instances was wrong", 1, results.size());
        MapHolder holder = (MapHolder) results.get(0);
        assertEquals("Result instance has wrong name", "Third", holder.getName());
        tx.commit();
    } catch (Exception e) {
        e.printStackTrace();
        fail("Exception thrown during query execution " + e.getMessage());
    } finally {
        if (tx.isActive()) {
            tx.rollback();
        }
        pm.close();
    }
}
Also used : JDOQLCompiler(org.datanucleus.query.compiler.JDOQLCompiler) Query(org.datanucleus.store.query.Query) JDOQuery(org.datanucleus.api.jdo.JDOQuery) PersistenceManager(javax.jdo.PersistenceManager) MapHolder(org.jpox.samples.one_many.map.MapHolder) HashMap(java.util.HashMap) JavaQueryInMemoryEvaluator(org.datanucleus.query.inmemory.JavaQueryInMemoryEvaluator) ArrayList(java.util.ArrayList) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) JDOQLInMemoryEvaluator(org.datanucleus.query.inmemory.JDOQLInMemoryEvaluator) JDOQuery(org.datanucleus.api.jdo.JDOQuery) JavaQueryCompiler(org.datanucleus.query.compiler.JavaQueryCompiler) Transaction(javax.jdo.Transaction) ArrayList(java.util.ArrayList) List(java.util.List) QueryCompilation(org.datanucleus.query.compiler.QueryCompilation)

Example 19 with Query

use of org.datanucleus.store.query.Query in project tests by datanucleus.

the class JDOQLEvaluatorTest method testFilterMapContainsValueNonPC.

/**
 * Test of filter with mapField.containsValue(nonPC).
 */
public void testFilterMapContainsValueNonPC() {
    PersistenceManager pm = pmf.getPersistenceManager();
    Transaction tx = pm.currentTransaction();
    try {
        tx.begin();
        // Create some instances to query over
        List<MapHolder> instances = new ArrayList<>();
        MapHolder holder1 = new MapHolder("First");
        MapHolder holder2 = new MapHolder("Second");
        MapHolder holder3 = new MapHolder("Third");
        holder1.getJoinMapNonNon().put("First", "First Element");
        holder2.getJoinMapNonNon().put("First", "First Element");
        holder2.getJoinMapNonNon().put("Second", "Second Element");
        holder3.getJoinMapNonNon().put("Second", "Second Element");
        holder3.getJoinMapNonNon().put("Third", "Third Element");
        instances.add(holder1);
        instances.add(holder2);
        instances.add(holder3);
        // Compile the query
        JDOQuery q = (JDOQuery) pm.newQuery(MapHolder.class, "joinMapNonNon.containsValue('Third Element')");
        Query query = q.getInternalQuery();
        ClassLoaderResolver clr = query.getExecutionContext().getClassLoaderResolver();
        JavaQueryCompiler compiler = new JDOQLCompiler(query.getExecutionContext().getNucleusContext(), clr, null, query.getCandidateClass(), null, query.getFilter(), query.getParsedImports(), query.getOrdering(), query.getResult(), query.getGrouping(), query.getHaving(), query.getExplicitParametersDeclaration(), query.getExplicitVariablesDeclaration(), null);
        QueryCompilation compilation = compiler.compile(new HashMap(), null);
        // Execute the query
        JavaQueryInMemoryEvaluator eval = new JDOQLInMemoryEvaluator(query, instances, compilation, null, clr);
        List results = (List) eval.execute(true, true, true, true, true);
        assertEquals("Number of result instances was wrong", 1, results.size());
        MapHolder holder = (MapHolder) results.get(0);
        assertEquals("Result instance has wrong name", "Third", holder.getName());
        tx.commit();
    } catch (Exception e) {
        e.printStackTrace();
        fail("Exception thrown during query execution " + e.getMessage());
    } finally {
        if (tx.isActive()) {
            tx.rollback();
        }
        pm.close();
    }
}
Also used : JDOQLCompiler(org.datanucleus.query.compiler.JDOQLCompiler) Query(org.datanucleus.store.query.Query) JDOQuery(org.datanucleus.api.jdo.JDOQuery) PersistenceManager(javax.jdo.PersistenceManager) MapHolder(org.jpox.samples.one_many.map.MapHolder) HashMap(java.util.HashMap) JavaQueryInMemoryEvaluator(org.datanucleus.query.inmemory.JavaQueryInMemoryEvaluator) ArrayList(java.util.ArrayList) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) JDOQLInMemoryEvaluator(org.datanucleus.query.inmemory.JDOQLInMemoryEvaluator) JDOQuery(org.datanucleus.api.jdo.JDOQuery) JavaQueryCompiler(org.datanucleus.query.compiler.JavaQueryCompiler) Transaction(javax.jdo.Transaction) ArrayList(java.util.ArrayList) List(java.util.List) QueryCompilation(org.datanucleus.query.compiler.QueryCompilation)

Example 20 with Query

use of org.datanucleus.store.query.Query in project tests by datanucleus.

the class JDOQLEvaluatorTest method testFilterInstanceOf.

/**
 * Test of filter with "instanceof".
 */
public void testFilterInstanceOf() {
    PersistenceManager pm = pmf.getPersistenceManager();
    Transaction tx = pm.currentTransaction();
    try {
        tx.begin();
        // Create some instances to query over
        List<Person> instances = new ArrayList<>();
        Person p1 = new Person(101, "Mickey", "Mouse", "mickey.mouse@warnerbros.com");
        p1.setAge(34);
        Employee p2 = new Employee(102, "Donald", "Duck", "donald.duck@warnerbros.com", 13400.0f, "12345");
        p2.setAge(38);
        Person p3 = new Person(103, "Minnie", "Mouse", "minnie.mouse@warnerbros.com");
        p3.setAge(31);
        instances.add(p1);
        instances.add(p2);
        instances.add(p3);
        // Compile the query
        JDOQuery q = (JDOQuery) pm.newQuery(Person.class, "this instanceof " + Employee.class.getName());
        Query query = q.getInternalQuery();
        ClassLoaderResolver clr = query.getExecutionContext().getClassLoaderResolver();
        JavaQueryCompiler compiler = new JDOQLCompiler(query.getExecutionContext().getNucleusContext(), clr, null, query.getCandidateClass(), null, query.getFilter(), query.getParsedImports(), query.getOrdering(), query.getResult(), query.getGrouping(), query.getHaving(), query.getExplicitParametersDeclaration(), query.getExplicitVariablesDeclaration(), null);
        QueryCompilation compilation = compiler.compile(new HashMap(), null);
        // Execute the query
        JavaQueryInMemoryEvaluator eval = new JDOQLInMemoryEvaluator(query, instances, compilation, null, clr);
        List results = (List) eval.execute(true, true, true, true, true);
        assertEquals("Number of result instances was wrong", 1, results.size());
        Person p = (Person) results.get(0);
        assertEquals("Result instance has wrong first name", "Donald", p.getFirstName());
        assertEquals("Result instance has wrong last name", "Duck", p.getLastName());
        assertEquals("Person number of result instance is wrong", 102, p.getPersonNum());
        assertEquals("Age of result instance is wrong", 38, p.getAge());
        tx.commit();
    } catch (Exception e) {
        e.printStackTrace();
        fail("Exception thrown during query execution " + e.getMessage());
    } finally {
        if (tx.isActive()) {
            tx.rollback();
        }
        pm.close();
    }
}
Also used : JDOQLCompiler(org.datanucleus.query.compiler.JDOQLCompiler) Query(org.datanucleus.store.query.Query) JDOQuery(org.datanucleus.api.jdo.JDOQuery) PersistenceManager(javax.jdo.PersistenceManager) HashMap(java.util.HashMap) JavaQueryInMemoryEvaluator(org.datanucleus.query.inmemory.JavaQueryInMemoryEvaluator) ArrayList(java.util.ArrayList) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) JDOQLInMemoryEvaluator(org.datanucleus.query.inmemory.JDOQLInMemoryEvaluator) JDOQuery(org.datanucleus.api.jdo.JDOQuery) Employee(org.jpox.samples.models.company.Employee) JavaQueryCompiler(org.datanucleus.query.compiler.JavaQueryCompiler) Transaction(javax.jdo.Transaction) ArrayList(java.util.ArrayList) List(java.util.List) QueryCompilation(org.datanucleus.query.compiler.QueryCompilation) Person(org.jpox.samples.models.company.Person)

Aggregations

Query (org.datanucleus.store.query.Query)24 JDOQuery (org.datanucleus.api.jdo.JDOQuery)21 List (java.util.List)16 QueryCompilation (org.datanucleus.query.compiler.QueryCompilation)16 ArrayList (java.util.ArrayList)15 HashMap (java.util.HashMap)15 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)15 PersistenceManager (javax.jdo.PersistenceManager)14 Transaction (javax.jdo.Transaction)14 JDOQLCompiler (org.datanucleus.query.compiler.JDOQLCompiler)14 JavaQueryCompiler (org.datanucleus.query.compiler.JavaQueryCompiler)14 JDOQLInMemoryEvaluator (org.datanucleus.query.inmemory.JDOQLInMemoryEvaluator)14 JavaQueryInMemoryEvaluator (org.datanucleus.query.inmemory.JavaQueryInMemoryEvaluator)14 Person (org.jpox.samples.models.company.Person)10 JDOQLTypedQuery (javax.jdo.JDOQLTypedQuery)7 NucleusException (org.datanucleus.exceptions.NucleusException)4 Iterator (java.util.Iterator)3 JDOException (javax.jdo.JDOException)2 JDOUnsupportedOptionException (javax.jdo.JDOUnsupportedOptionException)2 Employee (org.jpox.samples.models.company.Employee)2