blob: 0c0a4ff3185e8cefee095ca53676bcb85db8e49b [file] [log] [blame]
/*
* 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.Iterator;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.DerbyDictionary;
import org.apache.openjpa.jdbc.sql.SolidDBDictionary;
import org.apache.openjpa.persistence.simple.AllFieldTypes;
import org.apache.openjpa.persistence.test.SingleEMTestCase;
/**
* <p>Tests grouping and having capabilities.</p>
*
* @author Abe White
*/
public abstract class GroupingTestCase
extends SingleEMTestCase {
protected abstract void prepareQuery(Query q);
@Override
public void setUp() {
super.setUp(AllFieldTypes.class, CLEAR_TABLES,
"openjpa.Compatibility", "JPQL=warn");
AllFieldTypes pc1 = new AllFieldTypes();
AllFieldTypes pc2 = new AllFieldTypes();
AllFieldTypes pc3 = new AllFieldTypes();
AllFieldTypes pc4 = new AllFieldTypes();
// pc1 and pc2, pc3 and pc4 grouped on intField, shortField
pc1.setIntField(1);
pc1.setShortField((short) -1);
pc2.setIntField(1);
pc2.setShortField((short) -1);
pc3.setIntField(2);
pc3.setShortField((short) -2);
pc4.setIntField(2);
pc4.setShortField((short) -2);
// pc1 and pc2 grouped on stringField
pc1.setStringField("abc");
pc2.setStringField("acd");
pc3.setStringField("def");
pc4.setStringField("efg");
// pc2 and pc3 grouped on byteField
pc2.setByteField((byte) 1);
pc3.setByteField((byte) 1);
pc1.setByteField((byte) 0);
pc4.setByteField((byte) 2);
// longField is unique id
pc1.setLongField(1L);
pc2.setLongField(2L);
pc3.setLongField(3L);
pc4.setLongField(4L);
// set up some relations
pc1.setSelfOneOne(pc4);
pc2.setSelfOneOne(pc3);
pc3.setSelfOneOne(pc2);
pc4.setSelfOneOne(pc1);
// if variable testing, set up some 1-Ms instead of the 1-1s above
if (getName().startsWith("testVariable")) {
pc1.setSelfOneOne(pc1);
pc2.setSelfOneOne(pc1);
pc1.getSelfOneMany().add(pc1);
pc1.getSelfOneMany().add(pc2);
pc3.setSelfOneOne(pc3);
pc4.setSelfOneOne(pc3);
pc3.getSelfOneMany().add(pc3);
pc3.getSelfOneMany().add(pc4);
}
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(pc1);
em.persist(pc2);
em.persist(pc3);
em.persist(pc4);
em.getTransaction().commit();
em.close();
}
public void testSimpleGroup() {
Query q = em.createQuery("select o.intField from AllFieldTypes o " +
"group by o.intField order by o.intField asc");
prepareQuery(q);
List res = q.getResultList();
assertEquals(2, res.size());
Iterator itr = res.iterator();
assertEquals(1, itr.next());
assertEquals(2, itr.next());
assertTrue(!itr.hasNext());
}
public void testOrderByAggregate() {
// this is an extension of JPQL
Query q = em.createQuery("select sum(o.shortField) " +
"from AllFieldTypes o"
+ " group by o.intField order by sum(o.shortField) asc");
prepareQuery(q);
// this might fail in MySQL/MariaDB
List res = q.getResultList();
assertEquals(2, res.size());
Iterator itr = res.iterator();
assertEquals((long) -4, itr.next());
assertEquals((long) -2, itr.next());
assertTrue(!itr.hasNext());
}
public void testCompoundGroupSame() {
Query q = em.createQuery("select o.intField from AllFieldTypes o " +
"group by o.intField, o.shortField order by o.shortField asc");
prepareQuery(q);
List res = q.getResultList();
assertEquals(2, res.size());
Iterator itr = res.iterator();
assertEquals(2, itr.next());
assertEquals(1, itr.next());
assertTrue(!itr.hasNext());
}
public void testCompoundGroupDifferent() {
Query q = em.createQuery("select o.intField from AllFieldTypes o " +
"group by o.intField, o.byteField order by o.intField asc");
prepareQuery(q);
List res = q.getResultList();
assertEquals(4, res.size());
Iterator itr = res.iterator();
assertEquals(1, itr.next());
assertEquals(1, itr.next());
assertEquals(2, itr.next());
assertEquals(2, itr.next());
assertTrue(!itr.hasNext());
}
public void testDifferentGroupLengths() {
Query q = em.createQuery("select o.byteField from AllFieldTypes o"
+ " group by o.byteField order by o.byteField asc");
prepareQuery(q);
List res = q.getResultList();
assertEquals(3, res.size());
Iterator itr = res.iterator();
assertEquals((byte) 0, itr.next());
assertEquals((byte) 1, itr.next());
assertEquals((byte) 2, itr.next());
assertTrue(!itr.hasNext());
}
public void testGroupRelationField() {
Query q = em.createQuery("select o.selfOneOne.intField " +
"from AllFieldTypes o group by o.selfOneOne.intField " +
"order by o.selfOneOne.intField asc");
prepareQuery(q);
List res = q.getResultList();
assertEquals(2, res.size());
Iterator itr = res.iterator();
assertEquals(1, itr.next());
assertEquals(2, itr.next());
assertTrue(!itr.hasNext());
}
public void testSubstringInGroupBy() {
DBDictionary dict = ((JDBCConfiguration)emf.getConfiguration()).getDBDictionaryInstance();
if (dict instanceof SolidDBDictionary)
return;
// this is an extension of JPQL
Query q = em.createQuery("select substring(o.stringField, 1, 1), " +
"count(o) from AllFieldTypes o " +
"group by substring(o.stringField, 1, 1)");
prepareQuery(q);
List res = q.getResultList();
assertEquals(3, res.size());
q = em.createQuery("select substring(o.stringField, 1, 2), count(o) " +
"from AllFieldTypes o group by substring(o.stringField, 1, 2)");
prepareQuery(q);
res = q.getResultList();
assertEquals(4, res.size());
}
public void testGroupedAggregate() {
Query q = em.createQuery("select count(o) from AllFieldTypes o " +
"group by o.byteField order by o.byteField asc");
prepareQuery(q);
List res = q.getResultList();
assertEquals(3, res.size());
Iterator itr = res.iterator();
assertEquals(1L, itr.next());
assertEquals(2L, itr.next());
assertEquals(1L, itr.next());
assertTrue(!itr.hasNext());
}
public void testGroupedRelationAggregate() {
Query q = em.createQuery("select count(o), max(o.selfOneOne.longField)"
+ " from AllFieldTypes o group by o.intField"
+ " order by o.intField asc");
List res = q.getResultList();
assertEquals(2, res.size());
Iterator itr = res.iterator();
Object[] o = (Object[]) itr.next();
assertEquals(2L, o[0]);
assertEquals(4L, o[1]);
o = (Object[]) itr.next();
assertEquals(2L, o[0]);
assertEquals(2L, o[1]);
assertTrue(!itr.hasNext());
}
public void testGroupedMixedProjection() {
Query q = em.createQuery("select count(o), o.shortField " +
"from AllFieldTypes o group by o.intField, o.shortField " +
"order by o.intField asc");
prepareQuery(q);
List res = q.getResultList();
assertEquals(2, res.size());
Iterator itr = res.iterator();
Object[] o = (Object[]) itr.next();
assertEquals(2L, o[0]);
assertEquals((short) -1, o[1]);
o = (Object[]) itr.next();
assertEquals(2L, o[0]);
assertEquals((short) -2, o[1]);
assertTrue(!itr.hasNext());
}
public void testSimpleHaving() {
Query q = em.createQuery("select o.intField from AllFieldTypes o " +
"group by o.intField having o.intField < 2");
prepareQuery(q);
assertEquals(1, q.getSingleResult());
}
public void testAggregateHaving() {
Query q = em.createQuery("select o.byteField from AllFieldTypes o " +
"group by o.byteField having count(o) > 1");
prepareQuery(q);
assertEquals((byte) 1, q.getSingleResult());
}
public void testMixedHaving() {
Query q = em.createQuery("select o.byteField from AllFieldTypes o " +
"group by o.byteField having count(o) > 1 or o.byteField = 0 " +
"order by o.byteField asc");
prepareQuery(q);
List res = q.getResultList();
assertEquals(2, res.size());
Iterator itr = res.iterator();
assertEquals((byte) 0, itr.next());
assertEquals((byte) 1, itr.next());
assertTrue(!itr.hasNext());
}
public void testVariableGroup() {
Query q = em.createQuery("select max(other.longField) " +
"from AllFieldTypes o, AllFieldTypes other " +
"where other member of o.selfOneMany " +
"group by other.intField order by other.intField asc");
prepareQuery(q);
List res = q.getResultList();
assertEquals(2, res.size());
Iterator itr = res.iterator();
assertEquals(2L, itr.next());
assertEquals(4L, itr.next());
assertTrue(!itr.hasNext());
}
public void testVariableHaving() {
JDBCConfiguration conf = (JDBCConfiguration) em.getConfiguration();
DBDictionary dict = conf.getDBDictionaryInstance();
if (dict instanceof DerbyDictionary) {
// This test fails on Derby 10.5.3.0, so just skip it...
return;
}
Query q = em.createQuery("select max(o.longField), other.byteField " +
"from AllFieldTypes o, AllFieldTypes other " +
"where other member of o.selfOneMany " +
"group by other.byteField having sum(other.intField) = 2");
prepareQuery(q);
assertEquals(3L, ((Object[])q.getSingleResult())[0]);
}
}