You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2008/12/23 21:08:39 UTC

svn commit: r729084 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java openjpa-slice/src/test/java/org/apache/openjpa/slice/TestQuery.java

Author: ppoddar
Date: Tue Dec 23 12:08:39 2008
New Revision: 729084

URL: http://svn.apache.org/viewvc?rev=729084&view=rev
Log:
OPENJPA-845: Evaluate ordering value for PCPath to support ORDER BY slice queries that involves ordering terms not included in projection items and hence requires in-memory ordering from multiple slices.

Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
    openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestQuery.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java?rev=729084&r1=729083&r2=729084&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java Tue Dec 23 12:08:39 2008
@@ -36,13 +36,17 @@
 import org.apache.openjpa.jdbc.sql.Result;
 import org.apache.openjpa.jdbc.sql.SQLBuffer;
 import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.Broker;
 import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.StoreContext;
 import org.apache.openjpa.kernel.exps.CandidatePath;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.JavaTypes;
 import org.apache.openjpa.meta.XMLMetaData;
+import org.apache.openjpa.util.ImplHelper;
 import org.apache.openjpa.util.UserException;
 
 /**
@@ -556,6 +560,45 @@
                 return false;
         return true;
     }
+    
+    protected Object eval(Object candidate, Object orig,
+        StoreContext ctx, Object[] params) {
+        if (_actions == null)
+            return candidate;
+
+        Action action;
+        OpenJPAStateManager sm;
+        Broker tmpBroker;
+        for (Iterator itr = _actions.iterator(); itr.hasNext();) {
+            action = (Action)itr.next();
+            sm = null;
+            tmpBroker = null;
+            if (ImplHelper.isManageable(candidate))
+                sm = (OpenJPAStateManager) (ImplHelper.toPersistenceCapable(
+                    candidate, ctx.getConfiguration())).
+                    pcGetStateManager();
+            if (sm == null) {
+                tmpBroker = ctx.getBroker();
+                tmpBroker.transactional(candidate, false, null);
+                sm = tmpBroker.getStateManager(candidate);
+            }
+            if (action.op != Action.GET && action.op != Action.GET_OUTER)
+                continue;
+            try {
+                candidate = sm.fetchField(((FieldMapping)action.data).getIndex(), 
+                    true);
+            } catch (ClassCastException cce) {
+                throw new RuntimeException(action.data + " not a field path");
+            } finally {
+                // transactional does not clear the state, which is
+                // important since tmpCandidate might be also managed by
+                // another broker if it's a proxied non-pc instance
+                if (tmpBroker != null)
+                    tmpBroker.nontransactional(sm.getManagedInstance(), null);
+            }
+        }
+        return candidate;
+    }
 
     /**
      * Expression state.

Modified: openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestQuery.java?rev=729084&r1=729083&r2=729084&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestQuery.java (original)
+++ openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestQuery.java Tue Dec 23 12:08:39 2008
@@ -78,11 +78,12 @@
         em.getTransaction().commit();
     }
     
-    public void testQueryResultIsOrderedAcrossSlice() {
+    public void testOrderedQueryResultWhenOrderableItemSelected() {
         EntityManager em = emf.createEntityManager();
         em.getTransaction().begin();
         Query query = em.createQuery("SELECT p.value,p FROM PObject p ORDER BY p.value ASC");
         List result = query.getResultList();
+        assertValidResult(result);
         Integer old = Integer.MIN_VALUE;
         for (Object row : result) {
             Object[] line = (Object[])row;
@@ -95,6 +96,40 @@
         em.getTransaction().rollback();
     }
     
+    public void testOrderedQueryResultWhenOrderableItemNotSelected() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Query query = em.createQuery("SELECT p FROM PObject p ORDER BY p.value ASC");
+        List<PObject> result = query.getResultList();
+        assertValidResult(result);
+        Integer old = Integer.MIN_VALUE;
+        for (PObject pc : result) {
+            int value = pc.getValue();
+            assertTrue(value >= old);
+            old = value;
+        }
+        em.getTransaction().rollback();
+    }
+    
+    public void testOrderedQueryResultWhenNavigatedOrderableItemNotSelected() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Query query = em.createQuery("SELECT p FROM Person p JOIN p.address a ORDER BY a.zip ASC, a.city DESC");
+        List<Person> result = query.getResultList();
+        assertValidResult(result);
+        Integer oldZip = Integer.MIN_VALUE;
+        String oldCity = null;
+        for (Person pc : result) {
+            int zip = pc.getAddress().getZip();
+            String city = pc.getAddress().getCity();
+            assertTrue(zip >= oldZip);
+            assertTrue(oldCity == null || oldCity.compareTo(city) >= 0);
+            oldZip = zip;
+            oldCity = city;
+        }
+        em.getTransaction().rollback();
+    }
+    
     public void testAggregateQuery() {
         EntityManager em = emf.createEntityManager();
         em.getTransaction().begin();
@@ -128,15 +163,14 @@
         EntityManager em = emf.createEntityManager();
         int limit = 3;
         em.getTransaction().begin();
-        List result = em.createQuery("SELECT p.value,p FROM PObject p ORDER BY p.value ASC")
+        List<PObject> result = em.createQuery("SELECT p FROM PObject p ORDER BY p.value ASC")
             .setMaxResults(limit).getResultList();
-        int i = 0;
-        for (Object row : result) {
-            Object[] line = (Object[])row;
-            int value = ((Integer)line[0]).intValue();
-            PObject pc = (PObject)line[1];
-            System.err.println(++i + "." + SlicePersistence.getSlice(pc) + ":" 
-                    + pc.getId() + "," + pc.getValue());
+        assertValidResult(result);
+        Integer old = Integer.MIN_VALUE;
+        for (PObject pc : result) {
+            int value = pc.getValue();
+            assertTrue(value >= old);
+            old = value;
         }
         assertEquals(limit, result.size());
         em.getTransaction().rollback();
@@ -190,4 +224,10 @@
         assertEquals("Rome", p.getAddress().getCity());
         em.getTransaction().rollback();
     }
+    
+    void assertValidResult(List result) {
+        assertNotNull(result);
+        assertFalse(result.isEmpty());
+        assertTrue(result.size() > 1);
+    }
 }