Skip to content

Commit

Permalink
[jOOQ#1334] Fix inaccurate simulation of TRUNC(number, decimals) for …
Browse files Browse the repository at this point in the history
…Derby
  • Loading branch information
lukaseder committed May 11, 2012
1 parent e53a757 commit c1ae591
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
24 changes: 23 additions & 1 deletion jOOQ-test/src/org/jooq/test/_/testcases/FunctionTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,15 @@ public void testFunctionsOnNumbers() throws Exception {
Field<Double> f3d = floor(-2.0);
Field<Double> f4d = ceil(-2.0);

Field<Float> f1e = round(0.0f);
Field<Float> f2e = round(0.0f, 2);
Field<Float> f3e = floor(0.0f);
Field<Float> f4e = ceil(0.0f);
Field<Float> f1f = round(0.0f);
Field<Float> f2f = round(0.0f, 2);
Field<Float> f3f = floor(0.0f);
Field<Float> f4f = ceil(0.0f);

// Some arbitrary checks on having multiple select clauses
Record record =
create().select(f1a)
Expand All @@ -611,7 +620,10 @@ public void testFunctionsOnNumbers() throws Exception {
.select(f5a, f6a, f7a)
.select(f1b, f2b, f3b, f4b, f6b, f6b, f7b)
.select(f1c, f2c, f3c, f4c)
.select(f1d, f2d, f3d, f4d).fetchOne();
.select(f1d, f2d, f3d, f4d)
.select(f1e, f2e, f3e, f4e)
.select(f1f, f2f, f3f, f4f)
.fetchOne();

assertNotNull(record);
assertEquals("1.0", record.getValueAsString(f1a));
Expand Down Expand Up @@ -640,6 +652,16 @@ public void testFunctionsOnNumbers() throws Exception {
assertEquals("-2.0", record.getValueAsString(f3d));
assertEquals("-2.0", record.getValueAsString(f4d));

assertEquals("0.0", record.getValueAsString(f1e));
assertEquals("0.0", record.getValueAsString(f2e));
assertEquals("0.0", record.getValueAsString(f3e));
assertEquals("0.0", record.getValueAsString(f4e));

assertEquals("0.0", record.getValueAsString(f1f));
assertEquals("0.0", record.getValueAsString(f2f));
assertEquals("0.0", record.getValueAsString(f3f));
assertEquals("0.0", record.getValueAsString(f4f));

// Greatest and least
record = create().select(
greatest(1, 2, 3, 4),
Expand Down
17 changes: 14 additions & 3 deletions jOOQ/src/main/java/org/jooq/impl/Trunc.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@
*/
package org.jooq.impl;

import static java.math.BigDecimal.TEN;
import static org.jooq.impl.Factory.field;
import static org.jooq.impl.Factory.inline;
import static org.jooq.impl.Factory.one;
import static org.jooq.impl.Factory.zero;
import static org.jooq.impl.Util.extractVal;

import java.math.BigDecimal;
import java.math.MathContext;

import org.jooq.Configuration;
import org.jooq.Field;
Expand Down Expand Up @@ -82,10 +85,18 @@ private final Field<T> getDateTimeFunction(Configuration configuration) {
private final Field<T> getNumericFunction(Configuration configuration) {
switch (configuration.getDialect()) {
case ASE:

// This calculation is inaccurate for Derby
case DERBY: {
Field<BigDecimal> power = Factory.power(inline(new BigDecimal("10.0")), decimals);
Field<BigDecimal> power;

// [#1334] if possible, calculate the power in Java to prevent
// inaccurate arithmetics in the Derby database
Integer decimalsVal = extractVal(decimals);
if (decimalsVal != null) {
power = inline(TEN.pow(decimalsVal, MathContext.DECIMAL128));
}
else {
power = Factory.power(inline(TEN), decimals);
}

return Factory.decode()
.when(field.sign().greaterOrEqual(zero()),
Expand Down
19 changes: 19 additions & 0 deletions jOOQ/src/main/java/org/jooq/impl/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -1028,4 +1028,23 @@ static final Field<String> escapeForLike(Field<?> field) {
return field.cast(String.class);
}
}

/**
* Utility method to check whether a field is a {@link Param}
*/
static final boolean isVal(Field<?> field) {
return field instanceof Param;
}

/**
* Utility method to extract a value from a field
*/
static final <T> T extractVal(Field<T> field) {
if (isVal(field)) {
return ((Param<T>) field).getValue();
}
else {
return null;
}
}
}

0 comments on commit c1ae591

Please sign in to comment.