HHH-5078 : JPA criteria query numeric expressions produce wrong result (due to wrong bracketing)

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@19458 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Gail Badner 2010-05-10 22:18:47 +00:00
parent bb8f915859
commit 36a2ef2699
2 changed files with 92 additions and 6 deletions

View File

@ -43,27 +43,27 @@ public class BinaryArithmeticOperation<N extends Number>
public static enum Operation {
ADD {
String apply(String lhs, String rhs) {
return lhs + " + " + rhs;
return applyPrimitive( lhs, '+', rhs );
}
},
SUBTRACT {
String apply(String lhs, String rhs) {
return lhs + " - " + rhs;
return applyPrimitive( lhs, '-', rhs );
}
},
MULTIPLY {
String apply(String lhs, String rhs) {
return lhs + " * " + rhs;
return applyPrimitive( lhs, '*', rhs );
}
},
DIVIDE {
String apply(String lhs, String rhs) {
return lhs + " / " + rhs;
return applyPrimitive( lhs, '/', rhs );
}
},
QUOT {
String apply(String lhs, String rhs) {
return lhs + " / " + rhs;
return applyPrimitive( lhs, '/', rhs );
}
},
MOD {
@ -73,6 +73,18 @@ public class BinaryArithmeticOperation<N extends Number>
}
};
abstract String apply(String lhs, String rhs);
private static final char LEFT_PAREN = '(';
private static final char RIGHT_PAREN = ')';
private static String applyPrimitive(String lhs, char operator, String rhs) {
return new StringBuffer( lhs.length() + rhs.length() + 3 )
.append( LEFT_PAREN )
.append( lhs )
.append( operator )
.append( rhs )
.append( RIGHT_PAREN )
.toString();
}
}
private final Operation operator;

View File

@ -63,7 +63,7 @@ public class ExpressionsTest extends AbstractMetamodelSpecificTest {
@Override
public void tearDown() throws Exception {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
em.getTransaction().begin();
em.createQuery( "delete Product" ).executeUpdate();
em.getTransaction().commit();
em.close();
@ -153,4 +153,78 @@ public class ExpressionsTest extends AbstractMetamodelSpecificTest {
em.getTransaction().commit();
em.close();
}
public void testDiffWithQuotient() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaQuery<Number> criteria = builder.createQuery( Number.class );
criteria.from( Product.class );
criteria.select(
builder.quot(
builder.diff(
builder.literal( BigDecimal.valueOf( 2.0 ) ),
builder.literal( BigDecimal.valueOf( 1.0 ) )
),
BigDecimal.valueOf( 2.0 )
)
);
Number result = em.createQuery( criteria ).getSingleResult();
assertEquals(0.5d, result.doubleValue(), 0.1d);
em.getTransaction().commit();
em.close();
}
public void testSumWithQuotient() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaQuery<Number> criteria = builder.createQuery( Number.class );
criteria.from( Product.class );
criteria.select(
builder.quot(
builder.sum(
builder.literal( BigDecimal.valueOf( 0.0 ) ),
builder.literal( BigDecimal.valueOf( 1.0 ) )
),
BigDecimal.valueOf( 2.0 )
)
);
Number result = em.createQuery( criteria ).getSingleResult();
assertEquals(0.5d, result.doubleValue(), 0.1d);
em.getTransaction().commit();
em.close();
}
public void testQuotientAndMultiply() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaQuery<Number> criteria = builder.createQuery( Number.class );
criteria.from( Product.class );
criteria.select(
builder.quot(
builder.prod(
builder.literal( BigDecimal.valueOf( 10.0 ) ),
builder.literal( BigDecimal.valueOf( 5.0 ) )
),
BigDecimal.valueOf( 2.0 )
)
);
Number result = em.createQuery( criteria ).getSingleResult();
assertEquals(25.0d, result.doubleValue(), 0.1d);
criteria.select(
builder.prod(
builder.quot(
builder.literal( BigDecimal.valueOf( 10.0 ) ),
builder.literal( BigDecimal.valueOf( 5.0 ) )
),
BigDecimal.valueOf( 2.0 )
)
);
result = em.createQuery( criteria ).getSingleResult();
assertEquals(4.0d, result.doubleValue(), 0.1d);
em.getTransaction().commit();
em.close();
}
}