Skip to content
This repository
Browse code

[#1334] Fix inaccurate simulation of TRUNC(number, decimals) for Derby

  • Loading branch information...
commit c1ae59160b35a7b1d4a6c60fd7a59dff3033201f 1 parent e53a757
Lukas Eder authored May 11, 2012
24  jOOQ-test/src/org/jooq/test/_/testcases/FunctionTests.java
@@ -603,6 +603,15 @@ public void testFunctionsOnNumbers() throws Exception {
603 603
         Field<Double> f3d = floor(-2.0);
604 604
         Field<Double> f4d = ceil(-2.0);
605 605
 
  606
+        Field<Float> f1e = round(0.0f);
  607
+        Field<Float> f2e = round(0.0f, 2);
  608
+        Field<Float> f3e = floor(0.0f);
  609
+        Field<Float> f4e = ceil(0.0f);
  610
+        Field<Float> f1f = round(0.0f);
  611
+        Field<Float> f2f = round(0.0f, 2);
  612
+        Field<Float> f3f = floor(0.0f);
  613
+        Field<Float> f4f = ceil(0.0f);
  614
+
606 615
         // Some arbitrary checks on having multiple select clauses
607 616
         Record record =
608 617
         create().select(f1a)
@@ -611,7 +620,10 @@ public void testFunctionsOnNumbers() throws Exception {
611 620
                 .select(f5a, f6a, f7a)
612 621
                 .select(f1b, f2b, f3b, f4b, f6b, f6b, f7b)
613 622
                 .select(f1c, f2c, f3c, f4c)
614  
-                .select(f1d, f2d, f3d, f4d).fetchOne();
  623
+                .select(f1d, f2d, f3d, f4d)
  624
+                .select(f1e, f2e, f3e, f4e)
  625
+                .select(f1f, f2f, f3f, f4f)
  626
+                .fetchOne();
615 627
 
616 628
         assertNotNull(record);
617 629
         assertEquals("1.0", record.getValueAsString(f1a));
@@ -640,6 +652,16 @@ public void testFunctionsOnNumbers() throws Exception {
640 652
         assertEquals("-2.0", record.getValueAsString(f3d));
641 653
         assertEquals("-2.0", record.getValueAsString(f4d));
642 654
 
  655
+        assertEquals("0.0", record.getValueAsString(f1e));
  656
+        assertEquals("0.0", record.getValueAsString(f2e));
  657
+        assertEquals("0.0", record.getValueAsString(f3e));
  658
+        assertEquals("0.0", record.getValueAsString(f4e));
  659
+
  660
+        assertEquals("0.0", record.getValueAsString(f1f));
  661
+        assertEquals("0.0", record.getValueAsString(f2f));
  662
+        assertEquals("0.0", record.getValueAsString(f3f));
  663
+        assertEquals("0.0", record.getValueAsString(f4f));
  664
+
643 665
         // Greatest and least
644 666
         record = create().select(
645 667
             greatest(1, 2, 3, 4),
17  jOOQ/src/main/java/org/jooq/impl/Trunc.java
@@ -35,12 +35,15 @@
35 35
  */
36 36
 package org.jooq.impl;
37 37
 
  38
+import static java.math.BigDecimal.TEN;
38 39
 import static org.jooq.impl.Factory.field;
39 40
 import static org.jooq.impl.Factory.inline;
40 41
 import static org.jooq.impl.Factory.one;
41 42
 import static org.jooq.impl.Factory.zero;
  43
+import static org.jooq.impl.Util.extractVal;
42 44
 
43 45
 import java.math.BigDecimal;
  46
+import java.math.MathContext;
44 47
 
45 48
 import org.jooq.Configuration;
46 49
 import org.jooq.Field;
@@ -82,10 +85,18 @@
82 85
     private final Field<T> getNumericFunction(Configuration configuration) {
83 86
         switch (configuration.getDialect()) {
84 87
             case ASE:
85  
-
86  
-            // This calculation is inaccurate for Derby
87 88
             case DERBY: {
88  
-                Field<BigDecimal> power = Factory.power(inline(new BigDecimal("10.0")), decimals);
  89
+                Field<BigDecimal> power;
  90
+
  91
+                // [#1334] if possible, calculate the power in Java to prevent
  92
+                // inaccurate arithmetics in the Derby database
  93
+                Integer decimalsVal = extractVal(decimals);
  94
+                if (decimalsVal != null) {
  95
+                    power = inline(TEN.pow(decimalsVal, MathContext.DECIMAL128));
  96
+                }
  97
+                else {
  98
+                    power = Factory.power(inline(TEN), decimals);
  99
+                }
89 100
 
90 101
                 return Factory.decode()
91 102
                     .when(field.sign().greaterOrEqual(zero()),
19  jOOQ/src/main/java/org/jooq/impl/Util.java
@@ -1028,4 +1028,23 @@ static final String convertBytesToPostgresOctal(byte[] binary) {
1028 1028
             return field.cast(String.class);
1029 1029
         }
1030 1030
     }
  1031
+
  1032
+    /**
  1033
+     * Utility method to check whether a field is a {@link Param}
  1034
+     */
  1035
+    static final boolean isVal(Field<?> field) {
  1036
+        return field instanceof Param;
  1037
+    }
  1038
+
  1039
+    /**
  1040
+     * Utility method to extract a value from a field
  1041
+     */
  1042
+    static final <T> T extractVal(Field<T> field) {
  1043
+        if (isVal(field)) {
  1044
+            return ((Param<T>) field).getValue();
  1045
+        }
  1046
+        else {
  1047
+            return null;
  1048
+        }
  1049
+    }
1031 1050
 }

0 notes on commit c1ae591

Please sign in to comment.
Something went wrong with that request. Please try again.