You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2009/05/15 22:05:48 UTC

svn commit: r775306 - in /openjpa/trunk: openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/ openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/

Author: faywang
Date: Fri May 15 20:05:48 2009
New Revision: 775306

URL: http://svn.apache.org/viewvc?rev=775306&view=rev
Log:
OPENJPA-1013: TYPE expression support

Modified:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java?rev=775306&r1=775305&r2=775306&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java Fri May 15 20:05:48 2009
@@ -300,7 +300,6 @@
         assertEquivalence(q, jpql);
     }
     
-    @AllowFailure
     public void testExpression2() {
         String jpql = "SELECT TYPE(e) FROM Employee e WHERE TYPE(e) <> Exempt";
         CriteriaQuery q = cb.create();
@@ -425,7 +424,7 @@
     }
     
     @AllowFailure
-    public void testSelectList() {
+    public void testSelectList1() {
         String jpql = "SELECT v.location.street, KEY(i).title, VALUE(i) FROM " + 
             "VideoStore v JOIN v.videoInventory i WHERE v.location.zipCode = " + 
             "'94301' AND VALUE(i) > 0";
@@ -440,10 +439,12 @@
             inv.key().get(Movie_.title), inv.value());
         
         assertEquivalence(q, jpql);
-        
-        jpql = "SELECT NEW CustomerDetails(c.id, c.status, o.quantity) FROM " + 
-            "Customer c JOIN c.orders o WHERE o.quantity > 100";
-        q = cb.create();
+    }        
+    @AllowFailure
+    public void testSelectList2() {
+        String jpql = "SELECT NEW CustomerDetails(c.id, c.status, o.quantity) FROM " + 
+        "Customer c JOIN c.orders o WHERE o.quantity > 100";
+        CriteriaQuery q = cb.create();
         Root<Customer> c = q.from(Customer.class);
         Join<Customer, Order> o = c.join(Customer_.orders);
         q.where(cb.gt(o.get(Order_.quantity), 100));
@@ -456,7 +457,7 @@
     }
 
     @AllowFailure
-    public void testSubqueries() {
+    public void testSubqueries1() {
         String jpql = "SELECT goodCustomer FROM Customer goodCustomer WHERE " + 
             "goodCustomer.balanceOwed < (SELECT AVG(c.balanceOwed) FROM " + 
             "Customer c)";
@@ -469,39 +470,48 @@
         q.select(goodCustomer);
         
         assertEquivalence(q, jpql);
-        
-        jpql = "SELECT DISTINCT emp FROM Employee emp WHERE EXISTS (" + 
+    }
+    
+    @AllowFailure
+    public void testSubqueries2() {
+        String jpql = "SELECT DISTINCT emp FROM Employee emp WHERE EXISTS (" + 
             "SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp = " + 
             "emp.spouse)";
-        q = cb.create();
+        CriteriaQuery q = cb.create();
         Root<Employee> emp = q.from(Employee.class);
-        Subquery<Employee> sq1 = q.subquery(Employee.class);
-        Root<Employee> spouseEmp = sq1.from(Employee.class);
-        sq1.select(spouseEmp);
-        sq1.where(cb.equal(spouseEmp, emp.get(Employee_.spouse)));
+        Subquery<Employee> sq = q.subquery(Employee.class);
+        Root<Employee> spouseEmp = sq.from(Employee.class);
+        sq.select(spouseEmp);
+        sq.where(cb.equal(spouseEmp, emp.get(Employee_.spouse)));
         q.where(cb.exists(sq));
         q.select(emp).distinct(true);
         
         assertEquivalence(q, jpql);
-        
-        jpql = "SELECT emp FROM Employee emp WHERE emp.salary > ALL (" + 
+    }
+    
+    @AllowFailure
+    public void testSubqueries3() {
+        String jpql = "SELECT emp FROM Employee emp WHERE emp.salary > ALL (" + 
             "SELECT m.salary FROM Manager m WHERE m.department = " + 
             "emp.department)";
-        q = cb.create();
-        Root<Employee> emp1 = q.from(Employee.class);
-        q.select(emp1);
-        Subquery<BigDecimal> sq2 = q.subquery(BigDecimal.class);
-        Root<Manager> m = sq2.from(Manager.class);
-        sq2.select(m.get(Manager_.salary));
-        sq2.where(cb.equal(m.get(Manager_.department), emp1.get(
+        CriteriaQuery q = cb.create();
+        Root<Employee> emp = q.from(Employee.class);
+        q.select(emp);
+        Subquery<BigDecimal> sq = q.subquery(BigDecimal.class);
+        Root<Manager> m = sq.from(Manager.class);
+        sq.select(m.get(Manager_.salary));
+        sq.where(cb.equal(m.get(Manager_.department), emp.get(
             Employee_.department)));
         q.where(cb.gt(emp.get(Employee_.salary), cb.all(sq)));
-        
+    
         assertEquivalence(q, jpql);
-        
-        jpql = "SELECT c FROM Customer c WHERE " + 
+    }
+    
+    @AllowFailure
+    public void testSubqueries4() {
+        String jpql = "SELECT c FROM Customer c WHERE " + 
             "(SELECT COUNT(o) FROM c.orders o) > 10";
-        q = cb.create();
+        CriteriaQuery q = cb.create();
         Root<Customer> c1 = q.from(Customer.class);
         q.select(c1);
         Subquery<Long> sq3 = q.subquery(Long.class);
@@ -510,32 +520,38 @@
         q.where(cb.gt(sq3.select(cb.count(o)), 10));
         
         assertEquivalence(q, jpql);
-        
-        jpql = "SELECT o FROM Order o WHERE 10000 < ALL (" + 
+    }
+    
+    @AllowFailure
+    public void testSubqueries5() {
+        String jpql = "SELECT o FROM Order o WHERE 10000 < ALL (" + 
             "SELECT a.balance FROM o.customer c JOIN c.accounts a)";
-        q = cb.create();
-        Root<Order> o1 = q.from(Order.class);
-        q.select(o1);
-        Subquery<Integer> sq4 = q.subquery(Integer.class);
-        Root<Order> o2 = sq4.correlate(o1);
-        Join<Order,Customer> c3 = o2.join(Order_.customer);
-        Join<Customer,Account> a = c3.join(Customer_.accounts);
-        sq4.select(a.get(Account_.balance));
-        q.where(cb.lt(cb.literal(10000), cb.all(sq4)));
+        CriteriaQuery q = cb.create();
+        Root<Order> o = q.from(Order.class);
+        q.select(o);
+        Subquery<Integer> sq = q.subquery(Integer.class);
+        Root<Order> osq = sq.correlate(o);
+        Join<Order,Customer> c = osq.join(Order_.customer);
+        Join<Customer,Account> a = c.join(Customer_.accounts);
+        sq.select(a.get(Account_.balance));
+        q.where(cb.lt(cb.literal(10000), cb.all(sq)));
         
         assertEquivalence(q, jpql);
-
-        jpql = "SELECT o FROM Order o JOIN o.customer c WHERE 10000 < " +
+    }
+    
+    @AllowFailure
+    public void testSubqueries6() {
+        String jpql = "SELECT o FROM Order o JOIN o.customer c WHERE 10000 < " +
             "ALL (SELECT a.balance FROM c.accounts a)";
-        q = cb.create();
-        Root<Order> o3 = q.from(Order.class);
-        q.select(o3);
-        Join<Order,Customer> c4 = o3.join(Order_.customer);
-        Subquery<Integer> sq5 = q.subquery(Integer.class);
-        Join<Order,Customer> c5 = sq5.correlate(c4);
-        Join<Customer,Account> a2 = c5.join(Customer_.accounts);
-        sq5.select(a.get(Account_.balance));
-        q.where(cb.lt(cb.literal(10000), cb.all(sq5)));
+        CriteriaQuery q = cb.create();
+        Root<Order> o = q.from(Order.class);
+        q.select(o);
+        Join<Order,Customer> c = o.join(Order_.customer);
+        Subquery<Integer> sq = q.subquery(Integer.class);
+        Join<Order,Customer> csq = sq.correlate(c);
+        Join<Customer,Account> a = csq.join(Customer_.accounts);
+        sq.select(a.get(Account_.balance));
+        q.where(cb.lt(cb.literal(10000), cb.all(sq)));
         
         assertEquivalence(q, jpql);
     }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java?rev=775306&r1=775305&r2=775306&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java Fri May 15 20:05:48 2009
@@ -28,6 +28,7 @@
 import javax.persistence.criteria.QueryBuilder;
 import javax.persistence.criteria.QueryBuilder.Trimspec;
 
+import org.apache.openjpa.persistence.meta.Types;
 import org.apache.openjpa.kernel.exps.ExpressionFactory;
 import org.apache.openjpa.kernel.exps.Literal;
 import org.apache.openjpa.kernel.exps.Value;
@@ -458,6 +459,7 @@
     }
 
     public static class Equal extends BinaryLogicalExpression {
+        boolean negate;
         public <X,Y> Equal(Expression<X> x, Expression<Y> y) {
             super(x,y);
         }
@@ -466,12 +468,32 @@
             this(x, new Constant<Object>(Object.class, y));
         }
         
+        public Equal negate() {
+            negate = true;
+            return this;
+        }
+        
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
             ExpressionFactory factory, MetamodelImpl model) {
-                return factory.equal(
-                	Expressions.toValue(e1, factory, model), 
-                	Expressions.toValue(e2, factory, model));
+            boolean isTypeExpr = false;
+            Value val1 = Expressions.toValue(e1, factory, model);
+            Value val2 = Expressions.toValue(e2, factory, model);
+            if (e1 instanceof PathImpl) {
+                PathImpl path = (PathImpl)e1;
+                isTypeExpr = path.isTypeExpr();
+                if (isTypeExpr) {
+                    ((Constant)e2).setTypeLit(isTypeExpr);
+                    val2 = Expressions.toValue(e2, factory, model);
+                    Class clzz = (Class)((Literal)val2).getValue();
+                    val2.setMetaData(((Types.Managed)model.type(clzz)).meta);
+                }
+            }
+            
+            if (!negate)
+                return factory.equal(val1, val2);
+            else
+                return factory.notEqual(val1, val2);
         }
     }
     
@@ -564,6 +586,7 @@
     
     public static class Constant<X> extends ExpressionImpl<X> {
         public final Object arg;
+        private boolean typeLit;
         public Constant(Class<X> t, X x) {
             super(t);
             this.arg = x;
@@ -573,31 +596,49 @@
         	this((Class<X>)x.getClass(),x);
         }
         
+        public void setTypeLit(boolean typeLit) {
+            this.typeLit = typeLit;
+        }
+        
         @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model) {
-            return factory.newLiteral(arg, 1);
+            if (!typeLit)
+                return factory.newLiteral(arg, 1);
+            else
+                return factory.newTypeLiteral(arg, Literal.TYPE_CLASS);
         }
         
     }
     
     public static class IsEmpty extends PredicateImpl {
     	ExpressionImpl<?> collection;
+    	boolean negate;
     	public IsEmpty(Expression<?> collection) {
     		super();
     		this.collection = (ExpressionImpl<?>)collection;
     	}
     	
+    	public IsEmpty negate() {
+    	    negate = true;
+    	    return this;
+    	}
+    	
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
         	ExpressionFactory factory, MetamodelImpl model) {
-            return factory.isEmpty(
-            	Expressions.toValue(collection, factory, model));
+            if (!negate)
+                return factory.isEmpty(
+                    Expressions.toValue(collection, factory, model));
+            else
+                return factory.isNotEmpty(
+                    Expressions.toValue(collection, factory, model));
         }
     }
     
     public static class IsMember<E> extends PredicateImpl {
     	ExpressionImpl<E> element;
     	ExpressionImpl<?> collection;
+    	boolean negate;
     	
     	public IsMember(Class<E> t, Expression<E> element, 
     		Expression<?> collection) {
@@ -613,6 +654,11 @@
     		this((Class<E>)element.getClass(), element, collection);
     	}
     	
+    	public IsMember<E> negate() {
+    	    negate = true;
+    	    return this;
+    	}
+    	
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
         	ExpressionFactory factory, MetamodelImpl model) {

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java?rev=775306&r1=775305&r2=775306&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java Fri May 15 20:05:48 2009
@@ -42,6 +42,7 @@
 public class PathImpl<X> extends ExpressionImpl<X> implements Path<X> {
     private PathImpl<?> _parent;
     private Members.Member<?,X> member;
+    private boolean _isTypeExpr;
     
     /**
      * 
@@ -82,7 +83,8 @@
                 var.setImplicitType(getJavaType());
         }
         var.setAlias(getAlias());
-        
+        if (_isTypeExpr) 
+            var = factory.type(var);
         return var;
     }
 
@@ -114,8 +116,16 @@
     }
 
     public Expression<Class<? extends X>> type() {
-        // TODO Auto-generated method stub
-        throw new AbstractMethodError();
+        PathImpl<X> path = new PathImpl(getJavaType());
+        path.setTypeExpr(true);
+        return (Expression<Class<? extends X>>) path;
     }
 
+    public void setTypeExpr(boolean isTypeExpr) {
+        _isTypeExpr = isTypeExpr;
+    }
+    
+    public boolean isTypeExpr() {
+        return _isTypeExpr;
+    }
 }