diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java index ec2633177..8f45e8ef7 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java @@ -1403,6 +1403,30 @@ public class TestTypesafeCriteria extends CriteriaTest { cb.nullLiteral(String.class))); Query q = em.createQuery(cquery); - + } + + public void testCountDistinct() { + // JPQL Parser does not do well with the following + String jpql = "select DISTINCT COUNT(a.name) from Account a"; + + CriteriaQuery c = cb.createQuery(Long.class); + Root a = c.from(Account.class); + c.select(cb.countDistinct(a.get(Account_.name))); + + // hence we do not check equivalence against JPQL + // assertEquivalence(c, jpql); + // but check against SQL + String expectedSQL = "SELECT COUNT(DISTINCT t0.name) FROM CR_ACCT t0"; + executeAndCompareSQL(c, expectedSQL); + } + + public void testSizeReturnsInteger() { + String jpql = "select SIZE(c.accounts) from Customer c"; + CriteriaQuery c = cb.createQuery(Integer.class); + Root customer = c.from(Customer.class); + c.select(cb.size(customer.get(Customer_.accounts))); + + assertEquivalence(c, jpql); + } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java index 8ccf7bbca..fa5ff68ae 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java @@ -303,8 +303,8 @@ class Expressions { @Override public Value toValue(ExpressionFactory factory, CriteriaQueryImpl q) { - Value v = factory.count(Expressions.toValue(e, factory, q)); - return _distinct ? factory.distinct(v) : v; + Value v = Expressions.toValue(e, factory, q); + return _distinct ? factory.count(factory.distinct(v)) : factory.count(v); } @Override @@ -387,11 +387,14 @@ class Expressions { @Override public Value toValue(ExpressionFactory factory, CriteriaQueryImpl q) { Value val = Expressions.toValue(e, factory, q); + Value result; if (val instanceof Literal && ((Literal)val).getParseType() == Literal.TYPE_COLLECTION) - return factory.newLiteral(((Collection)((Literal)val).getValue()).size(), + result = factory.newLiteral(((Collection)((Literal)val).getValue()).size(), Literal.TYPE_NUMBER); - - return factory.size(val); + else + result = factory.size(val); + result.setImplicitType(Integer.class); + return result; } public StringBuilder asValue(AliasContext q) {