Author: fancy
Date: Sun Jul 13 20:46:44 2008
New Revision: 676467

URL: http://svn.apache.org/viewvc?rev=676467&view=rev
Log:
OPENJPA-51 Incorrect SQL with syntax error for JPQL subqueries

Added:
    
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
    
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
    
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
    
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
Modified:
    
openjpa/branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
    
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java

Modified: 
openjpa/branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=676467&r1=676466&r2=676467&view=diff
==============================================================================
--- 
openjpa/branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
 (original)
+++ 
openjpa/branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
 Sun Jul 13 20:46:44 2008
@@ -470,6 +470,63 @@
             else
                 _joinSyntax = _parent._joinSyntax;
         }
+        
+        if (_parent.getAliases() == null || _subPath == null)
+            return;
+        
+        // resolve aliases for subselect from parent
+        Set entries = _parent.getAliases().entrySet();
+        Iterator it = entries.iterator();
+        while (it.hasNext()) {
+               Map.Entry entry = (Map.Entry) it.next();
+            Object key = entry.getKey();
+            Integer alias = (Integer) entry.getValue();
+            if (key.toString().indexOf(_subPath) != -1) {
+                if (_aliases == null)
+                    _aliases = new HashMap();
+                _aliases.put(key, alias);
+
+                Object tableString = _parent.getTables().get(alias);
+                if (_tables == null)
+                    _tables = new TreeMap();
+                _tables.put(alias, tableString);
+                
+                _removedAliasFromParent.set(alias.intValue());
+            }
+        }
+        
+        if (_aliases != null) {
+            // aliases moved into subselect should be removed from parent
+            entries = _aliases.entrySet();
+            it = entries.iterator();
+            while (it.hasNext()) {
+               Map.Entry entry = (Map.Entry) it.next();
+                Object key = entry.getKey();
+                Integer alias = (Integer) entry.getValue();
+                if (key.toString().indexOf(_subPath) != -1) {
+                    _parent.removeAlias(key);
+
+                    Object tableString = _parent.getTables().get(alias);
+                    _parent.removeTable(alias);
+                }
+            }
+        }
+    }
+    
+    public Map getAliases() {
+        return _aliases;
+    }
+    
+    public void removeAlias(Object key) {
+        _aliases.remove(key);
+    }
+    
+    public Map getTables() {
+        return _tables;
+    }
+    
+    public void removeTable(Object key) {
+        _tables.remove(key);
     }
 
     public Select getFromSelect() {
@@ -1492,8 +1549,13 @@
             return;
         if (_parent._joins != null && !_parent._joins.isEmpty()) {
             boolean removed = false;
-            if (!_removedAliasFromParent.isEmpty())
-                removed = _parent._joins.joins().removeAll(pj.joins());
+            if (!_removedAliasFromParent.isEmpty()) {
+                for (Iterator itr = pj.joins().iterator(); itr.hasNext();) {
+                   Join jn = (Join) itr.next();
+                   if (_aliases.containsValue(new Integer(jn.getIndex1())))
+                       removed = _parent._joins.joins().remove(jn);
+                }
+            }
             if (!removed)
                 pj.joins().removeAll(_parent._joins.joins());
         }

Added: 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
URL: 
http://svn.apache.org/viewvc/openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java?rev=676467&view=auto
==============================================================================
--- 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
 (added)
+++ 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
 Sun Jul 13 20:46:44 2008
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.*;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.ArrayList;
+
[EMAIL PROTECTED]
[EMAIL PROTECTED](name="TCUSTOMER")
+public class Customer {
+
+    @Embeddable
+       public static class CustomerKey implements Serializable {
+               public String countryCode;
+               public int id;
+               
+               public CustomerKey(){}
+               
+               public  CustomerKey(String cc, int id){
+                       countryCode=cc;
+                       this.id=id;
+               }
+               
+               public String toString() {
+                       return countryCode+"/"+id;
+               }
+               @Override
+               public boolean equals(Object obj){
+                       if (obj==this) return true;
+                       if ( ! (obj instanceof CustomerKey) ) return false;
+                       CustomerKey key = (CustomerKey)obj;
+                       if (key.countryCode.equals(this.countryCode) && 
+                                       key.id==this.id) return true;
+                       return false;
+               }
+               
+               @Override
+               public int hashCode() {
+                       return this.countryCode.hashCode()
+                               ^ this.id;
+               }
+       }
+       
+       public enum CreditRating { POOR, GOOD, EXCELLENT };
+       
+       @EmbeddedId
+        CustomerKey cid;
+       @Column(length=30)
+    @Basic
+        String name;
+       @Enumerated
+    @Basic
+        CreditRating creditRating;
+       @Version
+        long version;
+       
+    @OneToMany(fetch=FetchType.EAGER, mappedBy="customer")
+    private Collection<Order> orders = new ArrayList<Order>();
+       
+       public Customer() {}
+       
+       public Customer(CustomerKey cid, String name, CreditRating rating){
+               this.cid=cid;
+               this.name=name;
+               this.creditRating=rating;
+       }
+       
+
+       public String getName() {
+               return name;
+       }
+       public void setName(String name) {
+               this.name = name;
+       }
+       public CreditRating getRating() {
+               return creditRating;
+       }
+       public void setRating(CreditRating rating) {
+               this.creditRating = rating;
+       }
+
+       public Collection<Order> getOrders() {
+               return orders;
+       }
+       public void setOrders(Collection<Order> orders) {
+               this.orders = orders;
+       }
+       
+       public String toString() {
+               return "Customer:"+cid+" name:"+name; 
+       }
+
+       public CustomerKey getCid() {
+               return cid;
+       }
+
+       public void setCid(CustomerKey cid) {
+               this.cid = cid;
+       }
+}
+

Added: 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
URL: 
http://svn.apache.org/viewvc/openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java?rev=676467&view=auto
==============================================================================
--- 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
 (added)
+++ 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
 Sun Jul 13 20:46:44 2008
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.*;
+
+import java.util.Collection;
+import java.util.ArrayList;
+
[EMAIL PROTECTED]
[EMAIL PROTECTED](name="TORDER")
+public class Order {
+       @Id 
+       @GeneratedValue(strategy=GenerationType.IDENTITY)
+        int oid;
+       
+        double amount;
+        boolean delivered;
+        
+       @ManyToOne (fetch=FetchType.EAGER)
+        Customer customer;
+       
+       @OneToMany (fetch=FetchType.EAGER , mappedBy="order")
+        Collection<OrderItem> lineitems = new ArrayList<OrderItem>();
+       @Version
+       long version;
+       
+       public Order(){}
+       
+       public Order(  double amt, boolean delivered, Customer c){
+               amount=amt;
+               this.delivered=delivered;
+               customer=c;
+               if (c!=null) c.getOrders().add(this);
+       }
+       
+       public double getAmount() {
+               return amount;
+       }
+       public void setAmount(double amount) {
+               this.amount = amount;
+       }
+       public Customer getCustomer() {
+               return customer;
+       }
+       public void setCustomer(Customer customer) {
+               this.customer = customer;
+       }
+       public boolean isDelivered() {
+               return delivered;
+       }
+       public void setDelivered(boolean delivered) {
+               this.delivered = delivered;
+       }
+       public int getOid() {
+               return oid;
+       }
+       
+       public String toString(){
+               return "Order:"+oid+" amount:"+amount+" delivered:"+delivered+" 
customer:"+
+                ( customer!=null ? customer.getCid()  :  -1 );
+       }
+
+       public Collection<OrderItem> getLineitems() {
+               return lineitems;
+       }
+
+       public void setLineitems(Collection<OrderItem> lineitems) {
+               this.lineitems = lineitems;
+       }
+}

Added: 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
URL: 
http://svn.apache.org/viewvc/openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java?rev=676467&view=auto
==============================================================================
--- 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
 (added)
+++ 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
 Sun Jul 13 20:46:44 2008
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+import javax.persistence.*;
[EMAIL PROTECTED]
[EMAIL PROTECTED](name="TORDERITEM")
+public class OrderItem {
+       @Id 
+       @GeneratedValue(strategy=GenerationType.IDENTITY)
+       int lid;
+       
+       int quantity;
+       double cost;
+        
+       @ManyToOne (fetch=FetchType.EAGER)
+       Order order;
+       
+       @Version
+       long version;
+       
+       public OrderItem(){}
+
+    public OrderItem( int quantity, double cost, Order o){
+        this.quantity=quantity;
+        this.cost=cost;
+        order = o;
+    }
+
+       public double getCost() {
+               return cost;
+       }
+
+       public void setCost(double cost) {
+               this.cost = cost;
+       }
+
+       public int getLid() {
+               return lid;
+       }
+
+       public void setLid(int lid) {
+               this.lid = lid;
+       }
+
+       public int getQuantity() {
+               return quantity;
+       }
+
+       public void setQuantity(int quantity) {
+               this.quantity = quantity;
+       }
+
+       public Order getOrder() {
+               return order;
+       }
+
+       public void setOrder(Order order) {
+               this.order = order;
+       }
+}

Added: 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
URL: 
http://svn.apache.org/viewvc/openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java?rev=676467&view=auto
==============================================================================
--- 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
 (added)
+++ 
openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
 Sun Jul 13 20:46:44 2008
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test JPQL subquery
+ */
+public class TestSubquery
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(Customer.class, Customer.CustomerKey.class,
+            Order.class, OrderItem.class, CLEAR_TABLES);
+    }
+
+    static String[]  querys = new String[] {
+        "select o.oid from Order o where o.customer.name =" +
+            " (select max(o2.customer.name) from Order o2" +
+            " where o.customer.cid.id = o2.customer.cid.id)",
+        "select o from Order o where o.customer.name =" +
+            " (select max(o2.customer.name) from Order o2" +
+            " where o.customer.cid.id = o2.customer.cid.id)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(i) from o.lineitems i)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(o.amount) from Order o)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(o.oid) from Order o)",
+        "select o.oid from Order o where o.amount >" +
+            " (select avg(o.amount) from Order o)",
+        "select c.name from Customer c where exists" +
+            " (select o from c.orders o where o.oid = 1) or exists" +
+            " (select o from c.orders o where o.oid = 2)",
+        "select c.name from Customer c, in(c.orders) o where o.amount between" 
+
+            " (select max(o.amount) from Order o) and" +
+            " (select avg(o.amount) from Order o) ",
+        "select o.oid from Order o where o.amount >" +
+            " (select sum(o2.amount) from Customer c, in(c.orders) o2) ",   
+        "select o.oid from Order o where o.amount between" +
+            " (select avg(o2.amount) from Customer c, in(c.orders) o2)" +
+            " and (select min(o2.amount) from Customer c, in(c.orders) o2)",
+        "select o.oid from Customer c, in(c.orders)o where o.amount >" +
+            " (select sum(o2.amount) from c.orders o2)",
+    // outstanding problem subqueries:
+    //"select o from Order o where o.amount > (select count(o) from Order o)",
+    //"select o from Order o where o.amount > (select count(o2) from Order 
o2)",
+    // "select c from Customer c left join c.orders p where not exists"
+    //   + " (select o2 from c.orders o2 where o2 = o",
+    };
+
+
+    static String[] updates = new String[] {
+        "update Order o set o.amount = 1000 where o.customer.name = " +
+            " (select max(o2.customer.name) from Order o2 " + 
+            " where o.customer.cid.id = o2.customer.cid.id)",  
+    };
+
+
+    public void testSubquery() {
+        EntityManager em = emf.createEntityManager();
+        for (int i = 0; i < querys.length; i++) {
+            String q = querys[i];
+            List rs = em.createQuery(q).getResultList();
+            assertEquals(0, rs.size());
+        }
+
+        em.getTransaction().begin();
+        for (int i = 0; i < updates.length; i++) {
+            int updateCount = em.createQuery(updates[i]).executeUpdate();
+            assertEquals(0, updateCount);
+        }
+
+        em.getTransaction().rollback();
+        em.close();
+    }
+}

Modified: 
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=676467&r1=676466&r2=676467&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
 Sun Jul 13 20:46:44 2008
@@ -573,6 +573,59 @@
             else
                 _joinSyntax = _parent._joinSyntax;
         }
+        
+        if (_parent.getAliases() == null || _subPath == null)
+            return;
+        
+        // resolve aliases for subselect from parent
+        Set<Map.Entry> entries = _parent.getAliases().entrySet();
+        for (Map.Entry entry : entries) {
+            Object key = entry.getKey();
+            Integer alias = (Integer) entry.getValue();
+            if (key.toString().indexOf(_subPath) != -1) {
+                if (_aliases == null)
+                    _aliases = new HashMap();
+                _aliases.put(key, alias);
+
+                Object tableString = _parent.getTables().get(alias);
+                if (_tables == null)
+                    _tables = new TreeMap();
+                _tables.put(alias, tableString);
+                
+                _removedAliasFromParent.set(alias.intValue());
+            }
+        }
+        
+        if (_aliases != null) {
+            // aliases moved into subselect should be removed from parent
+            entries = _aliases.entrySet();
+            for (Map.Entry entry : entries) {
+                Object key = entry.getKey();
+                Integer alias = (Integer) entry.getValue();
+                if (key.toString().indexOf(_subPath) != -1) {
+                    _parent.removeAlias(key);
+
+                    Object tableString = _parent.getTables().get(alias);
+                    _parent.removeTable(alias);
+                }
+            }
+        }
+    }
+    
+    public Map getAliases() {
+        return _aliases;
+    }
+    
+    public void removeAlias(Object key) {
+        _aliases.remove(key);
+    }
+    
+    public Map getTables() {
+        return _tables;
+    }
+    
+    public void removeTable(Object key) {
+        _tables.remove(key);
     }
 
     public Select getFromSelect() {
@@ -1645,8 +1698,13 @@
             return;
         if (_parent._joins != null && !_parent._joins.isEmpty()) {
             boolean removed = false;
-            if (!_removedAliasFromParent.isEmpty())
-                removed = _parent._joins.joins().removeAll(pj.joins());
+            if (!_removedAliasFromParent.isEmpty()) {
+                for (Iterator itr = pj.joins().iterator(); itr.hasNext();) {
+                   Join jn = (Join) itr.next();
+                   if (_aliases.containsValue(jn.getIndex1()))
+                       removed = _parent._joins.joins().remove(jn);
+                }
+            }
             if (!removed)
                 pj.joins().removeAll(_parent._joins.joins());
         }

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java?rev=676467&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
 Sun Jul 13 20:46:44 2008
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.*;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.ArrayList;
+
[EMAIL PROTECTED]
[EMAIL PROTECTED](name="TCUSTOMER")
+public class Customer {
+
+    @Embeddable
+       public static class CustomerKey implements Serializable {
+               public String countryCode;
+               public int id;
+               
+               public CustomerKey(){}
+               
+               public  CustomerKey(String cc, int id){
+                       countryCode=cc;
+                       this.id=id;
+               }
+               
+               public String toString() {
+                       return countryCode+"/"+id;
+               }
+               @Override
+               public boolean equals(Object obj){
+                       if (obj==this) return true;
+                       if ( ! (obj instanceof CustomerKey) ) return false;
+                       CustomerKey key = (CustomerKey)obj;
+                       if (key.countryCode.equals(this.countryCode) && 
+                                       key.id==this.id) return true;
+                       return false;
+               }
+               
+               @Override
+               public int hashCode() {
+                       return this.countryCode.hashCode()
+                               ^ this.id;
+               }
+       }
+       
+       public enum CreditRating { POOR, GOOD, EXCELLENT };
+       
+       @EmbeddedId
+        CustomerKey cid;
+       @Column(length=30)
+    @Basic
+        String name;
+       @Enumerated
+    @Basic
+        CreditRating creditRating;
+       @Version
+        long version;
+       
+    @OneToMany(fetch=FetchType.EAGER, mappedBy="customer")
+    private Collection<Order> orders = new ArrayList<Order>();
+       
+       public Customer() {}
+       
+       public Customer(CustomerKey cid, String name, CreditRating rating){
+               this.cid=cid;
+               this.name=name;
+               this.creditRating=rating;
+       }
+       
+
+       public String getName() {
+               return name;
+       }
+       public void setName(String name) {
+               this.name = name;
+       }
+       public CreditRating getRating() {
+               return creditRating;
+       }
+       public void setRating(CreditRating rating) {
+               this.creditRating = rating;
+       }
+
+       public Collection<Order> getOrders() {
+               return orders;
+       }
+       public void setOrders(Collection<Order> orders) {
+               this.orders = orders;
+       }
+       
+       public String toString() {
+               return "Customer:"+cid+" name:"+name; 
+       }
+
+       public CustomerKey getCid() {
+               return cid;
+       }
+
+       public void setCid(CustomerKey cid) {
+               this.cid = cid;
+       }
+}
+

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java?rev=676467&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
 Sun Jul 13 20:46:44 2008
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.*;
+
+import java.util.Collection;
+import java.util.ArrayList;
+
[EMAIL PROTECTED]
[EMAIL PROTECTED](name="TORDER")
+public class Order {
+       @Id 
+       @GeneratedValue(strategy=GenerationType.IDENTITY)
+        int oid;
+       
+        double amount;
+        boolean delivered;
+        
+       @ManyToOne (fetch=FetchType.EAGER)
+        Customer customer;
+       
+       @OneToMany (fetch=FetchType.EAGER , mappedBy="order")
+        Collection<OrderItem> lineitems = new ArrayList<OrderItem>();
+       @Version
+       long version;
+       
+       public Order(){}
+       
+       public Order(  double amt, boolean delivered, Customer c){
+               amount=amt;
+               this.delivered=delivered;
+               customer=c;
+               if (c!=null) c.getOrders().add(this);
+       }
+       
+       public double getAmount() {
+               return amount;
+       }
+       public void setAmount(double amount) {
+               this.amount = amount;
+       }
+       public Customer getCustomer() {
+               return customer;
+       }
+       public void setCustomer(Customer customer) {
+               this.customer = customer;
+       }
+       public boolean isDelivered() {
+               return delivered;
+       }
+       public void setDelivered(boolean delivered) {
+               this.delivered = delivered;
+       }
+       public int getOid() {
+               return oid;
+       }
+       
+       public String toString(){
+               return "Order:"+oid+" amount:"+amount+" delivered:"+delivered+" 
customer:"+
+                ( customer!=null ? customer.getCid()  :  -1 );
+       }
+
+       public Collection<OrderItem> getLineitems() {
+               return lineitems;
+       }
+
+       public void setLineitems(Collection<OrderItem> lineitems) {
+               this.lineitems = lineitems;
+       }
+}

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java?rev=676467&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
 Sun Jul 13 20:46:44 2008
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+import javax.persistence.*;
[EMAIL PROTECTED]
[EMAIL PROTECTED](name="TORDERITEM")
+public class OrderItem {
+       @Id 
+       @GeneratedValue(strategy=GenerationType.IDENTITY)
+       int lid;
+       
+       int quantity;
+       double cost;
+        
+       @ManyToOne (fetch=FetchType.EAGER)
+       Order order;
+       
+       @Version
+       long version;
+       
+       public OrderItem(){}
+
+    public OrderItem( int quantity, double cost, Order o){
+        this.quantity=quantity;
+        this.cost=cost;
+        order = o;
+    }
+
+       public double getCost() {
+               return cost;
+       }
+
+       public void setCost(double cost) {
+               this.cost = cost;
+       }
+
+       public int getLid() {
+               return lid;
+       }
+
+       public void setLid(int lid) {
+               this.lid = lid;
+       }
+
+       public int getQuantity() {
+               return quantity;
+       }
+
+       public void setQuantity(int quantity) {
+               this.quantity = quantity;
+       }
+
+       public Order getOrder() {
+               return order;
+       }
+
+       public void setOrder(Order order) {
+               this.order = order;
+       }
+}

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java?rev=676467&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
 Sun Jul 13 20:46:44 2008
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test JPQL subquery
+ */
+public class TestSubquery
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(Customer.class, Customer.CustomerKey.class,
+            Order.class, OrderItem.class, CLEAR_TABLES);
+    }
+
+    static String[]  querys = new String[] {
+        "select o.oid from Order o where o.customer.name =" +
+            " (select max(o2.customer.name) from Order o2" +
+            " where o.customer.cid.id = o2.customer.cid.id)",
+        "select o from Order o where o.customer.name =" +
+            " (select max(o2.customer.name) from Order o2" +
+            " where o.customer.cid.id = o2.customer.cid.id)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(i) from o.lineitems i)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(o.amount) from Order o)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(o.oid) from Order o)",
+        "select o.oid from Order o where o.amount >" +
+            " (select avg(o.amount) from Order o)",
+        "select c.name from Customer c where exists" +
+            " (select o from c.orders o where o.oid = 1) or exists" +
+            " (select o from c.orders o where o.oid = 2)",
+        "select c.name from Customer c, in(c.orders) o where o.amount between" 
+
+            " (select max(o.amount) from Order o) and" +
+            " (select avg(o.amount) from Order o) ",
+        "select o.oid from Order o where o.amount >" +
+            " (select sum(o2.amount) from Customer c, in(c.orders) o2) ",   
+        "select o.oid from Order o where o.amount between" +
+            " (select avg(o2.amount) from Customer c, in(c.orders) o2)" +
+            " and (select min(o2.amount) from Customer c, in(c.orders) o2)",
+        "select o.oid from Customer c, in(c.orders)o where o.amount >" +
+            " (select sum(o2.amount) from c.orders o2)",
+    // outstanding problem subqueries:
+    //"select o from Order o where o.amount > (select count(o) from Order o)",
+    //"select o from Order o where o.amount > (select count(o2) from Order 
o2)",
+    // "select c from Customer c left join c.orders p where not exists"
+    //   + " (select o2 from c.orders o2 where o2 = o",
+    };
+
+
+    static String[] updates = new String[] {
+        "update Order o set o.amount = 1000 where o.customer.name = " +
+            " (select max(o2.customer.name) from Order o2 " + 
+            " where o.customer.cid.id = o2.customer.cid.id)",  
+    };
+
+
+    public void testSubquery() {
+        EntityManager em = emf.createEntityManager();
+        for (int i = 0; i < querys.length; i++) {
+            String q = querys[i];
+            List rs = em.createQuery(q).getResultList();
+            assertEquals(0, rs.size());
+        }
+
+        em.getTransaction().begin();
+        for (int i = 0; i < updates.length; i++) {
+            int updateCount = em.createQuery(updates[i]).executeUpdate();
+            assertEquals(0, updateCount);
+        }
+
+        em.getTransaction().rollback();
+        em.close();
+    }
+}


Reply via email to