Repository: incubator-drill
Updated Branches:
  refs/heads/master dcc94a398 -> 810a20409


DRILL-1110: Output precision of functions should always be greater or equal to 
input precision


Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/e1cf5c2e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/e1cf5c2e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/e1cf5c2e

Branch: refs/heads/master
Commit: e1cf5c2e930e645c7085aae318796bf536ea8c10
Parents: e987e06
Author: Mehant Baid <[email protected]>
Authored: Sun Jul 6 09:57:01 2014 -0700
Committer: Jacques Nadeau <[email protected]>
Committed: Mon Jul 7 14:50:31 2014 -0700

----------------------------------------------------------------------
 .../DecimalScalePrecisionDivideFunction.java    |  5 +-
 .../util/DecimalScalePrecisionModFunction.java  | 43 +++++++++++
 .../templates/Decimal/DecimalFunctions.java     |  4 +-
 .../exec/expr/annotations/FunctionTemplate.java |  1 +
 .../expr/fn/DrillDecimalModScaleFuncHolder.java | 79 ++++++++++++++++++++
 .../drill/exec/expr/fn/FunctionConverter.java   |  3 +
 6 files changed, 132 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e1cf5c2e/common/src/main/java/org/apache/drill/common/util/DecimalScalePrecisionDivideFunction.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/util/DecimalScalePrecisionDivideFunction.java
 
b/common/src/main/java/org/apache/drill/common/util/DecimalScalePrecisionDivideFunction.java
index c4b33e4..4d3b939 100644
--- 
a/common/src/main/java/org/apache/drill/common/util/DecimalScalePrecisionDivideFunction.java
+++ 
b/common/src/main/java/org/apache/drill/common/util/DecimalScalePrecisionDivideFunction.java
@@ -45,7 +45,7 @@ public class DecimalScalePrecisionDivideFunction extends 
DrillBaseComputeScalePr
   @Override
   public void computeScalePrecision(int leftPrecision, int leftScale, int 
rightPrecision, int rightScale) {
 
-  // compute the output scale and precision here
+    // compute the output scale and precision here
     outputScale = leftScale + rightScale;
     int leftIntegerDigits = leftPrecision - leftScale;
     int maxResultIntegerDigits = leftIntegerDigits + rightScale;
@@ -53,6 +53,9 @@ public class DecimalScalePrecisionDivideFunction extends 
DrillBaseComputeScalePr
 
     outputPrecision = DecimalUtility.getPrecisionRange(outputScale + 
maxResultIntegerDigits);
 
+    // Output precision should be greater or equal to the input precision
+    outputPrecision = Math.max(outputPrecision, Math.max(leftPrecision, 
rightPrecision));
+
     // Try and increase the scale if we have any room
     outputScale = (outputPrecision - maxResultIntegerDigits >= 0) ? 
(outputPrecision - maxResultIntegerDigits) : 0;
   }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e1cf5c2e/common/src/main/java/org/apache/drill/common/util/DecimalScalePrecisionModFunction.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/util/DecimalScalePrecisionModFunction.java
 
b/common/src/main/java/org/apache/drill/common/util/DecimalScalePrecisionModFunction.java
new file mode 100644
index 0000000..e1e587b
--- /dev/null
+++ 
b/common/src/main/java/org/apache/drill/common/util/DecimalScalePrecisionModFunction.java
@@ -0,0 +1,43 @@
+/**
+ * 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.drill.common.util;
+
+public class DecimalScalePrecisionModFunction extends 
DrillBaseComputeScalePrecision {
+
+  public DecimalScalePrecisionModFunction(int leftPrecision, int leftScale, 
int rightPrecision, int rightScale) {
+    super(leftPrecision, leftScale, rightPrecision, rightScale);
+  }
+
+  @Override
+  public void computeScalePrecision(int leftPrecision, int leftScale, int 
rightPrecision, int rightScale) {
+
+    // compute the output scale and precision here
+    outputScale = Math.max(leftScale, rightScale);
+    int leftIntegerDigits = leftPrecision - leftScale;
+
+    outputPrecision = DecimalUtility.getPrecisionRange(outputScale + 
leftIntegerDigits);
+
+    if (outputScale + leftIntegerDigits > outputPrecision) {
+      outputScale = outputPrecision - leftIntegerDigits;
+    }
+
+    // Output precision should atleast be greater or equal to the input 
precision
+    outputPrecision = Math.max(outputPrecision, Math.max(leftPrecision, 
rightPrecision));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e1cf5c2e/exec/java-exec/src/main/codegen/templates/Decimal/DecimalFunctions.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/codegen/templates/Decimal/DecimalFunctions.java 
b/exec/java-exec/src/main/codegen/templates/Decimal/DecimalFunctions.java
index 27279f0..b5a69f1 100644
--- a/exec/java-exec/src/main/codegen/templates/Decimal/DecimalFunctions.java
+++ b/exec/java-exec/src/main/codegen/templates/Decimal/DecimalFunctions.java
@@ -556,7 +556,7 @@ public class ${type.name}Functions {
         }
     }
 
-    @FunctionTemplate(name = "mod", scope = 
FunctionTemplate.FunctionScope.DECIMAL_DIV_SCALE, nulls = 
NullHandling.NULL_IF_NULL)
+    @FunctionTemplate(name = "mod", scope = 
FunctionTemplate.FunctionScope.DECIMAL_MOD_SCALE, nulls = 
NullHandling.NULL_IF_NULL)
     public static class ${type.name}ModFunction implements DrillSimpleFunc {
 
         @Param ${type.name}Holder left;
@@ -1355,7 +1355,7 @@ public class ${type.name}Functions {
         }
     }
 
-    @FunctionTemplate(name = "mod", scope = 
FunctionTemplate.FunctionScope.DECIMAL_DIV_SCALE, nulls = 
NullHandling.NULL_IF_NULL)
+    @FunctionTemplate(name = "mod", scope = 
FunctionTemplate.FunctionScope.DECIMAL_MOD_SCALE, nulls = 
NullHandling.NULL_IF_NULL)
     public static class ${type.name}ModFunction implements DrillSimpleFunc {
 
         @Param ${type.name}Holder left;

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e1cf5c2e/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
index 78a22d8..bd4b7f1 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
@@ -63,6 +63,7 @@ public @interface FunctionTemplate {
     DECIMAL_MUL_SCALE,
     DECIMAL_CAST,
     DECIMAL_DIV_SCALE,
+    DECIMAL_MOD_SCALE,
     DECIMAL_ADD_SCALE,
     DECIMAL_SET_SCALE,
     DECIMAL_ZERO_SCALE,

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e1cf5c2e/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalModScaleFuncHolder.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalModScaleFuncHolder.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalModScaleFuncHolder.java
new file mode 100644
index 0000000..2cf1088
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalModScaleFuncHolder.java
@@ -0,0 +1,79 @@
+/**
+ * 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.drill.exec.expr.fn;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.types.TypeProtos;
+import org.apache.drill.common.types.TypeProtos.MajorType;
+
+import org.apache.drill.common.util.DecimalScalePrecisionDivideFunction;
+import org.apache.drill.common.util.DecimalScalePrecisionModFunction;
+import org.apache.drill.common.util.DecimalUtility;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+
+public class DrillDecimalModScaleFuncHolder extends DrillSimpleFuncHolder{
+
+
+  public DrillDecimalModScaleFuncHolder(FunctionScope scope, NullHandling 
nullHandling, boolean isBinaryCommutative, boolean isRandom,
+                                        String[] registeredNames, 
ValueReference[] parameters, ValueReference returnValue, WorkspaceReference[] 
workspaceVars,
+                                        Map<String, String> methods, 
List<String> imports) {
+    super(scope, nullHandling, isBinaryCommutative, isRandom, registeredNames, 
parameters, returnValue, workspaceVars, methods, imports);
+  }
+
+  /*
+   * This function scope is used by divide functions for decimal data type.
+   * DecimalScalePrecisionDivideFunction is used to compute the output types'
+   * scale and precision
+   */
+  @Override
+  public MajorType getReturnType(List<LogicalExpression> args) {
+
+    TypeProtos.DataMode mode = returnValue.type.getMode();
+
+    if (nullHandling == NullHandling.NULL_IF_NULL) {
+      // if any one of the input types is nullable, then return nullable 
return type
+      for (LogicalExpression e : args) {
+        if (e.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
+          mode = TypeProtos.DataMode.OPTIONAL;
+          break;
+        }
+      }
+    }
+
+
+    /* Get the result's scale and precision. This is a function scope for 
Divide function, assert we have
+     * only two inputs
+     */
+    assert args.size() == 2;
+
+    DecimalScalePrecisionModFunction outputScalePrec =
+        new 
DecimalScalePrecisionModFunction(args.get(0).getMajorType().getPrecision(), 
args.get(0).getMajorType().getScale(),
+            args.get(1).getMajorType().getPrecision(), 
args.get(1).getMajorType().getScale());
+    return 
(TypeProtos.MajorType.newBuilder().setMinorType(DecimalUtility.getDecimalDataType(outputScalePrec.getOutputPrecision()))
+        
.setScale(outputScalePrec.getOutputScale()).setPrecision(outputScalePrec.getOutputPrecision()).setMode(mode).build());
+  }
+
+  @Override
+  public boolean checkPrecisionRange() {
+    return true;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e1cf5c2e/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
index 1d7dd0b..64f45c7 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionConverter.java
@@ -259,6 +259,9 @@ public class FunctionConverter {
       case DECIMAL_DIV_SCALE:
           return new DrillDecimalDivScaleFuncHolder(template.scope(), 
template.nulls(), template.isBinaryCommutative(),
                   template.isRandom(), registeredNames, ps, outputField, 
works, methods, imports);
+      case DECIMAL_MOD_SCALE:
+          return new DrillDecimalModScaleFuncHolder(template.scope(), 
template.nulls(), template.isBinaryCommutative(),
+                  template.isRandom(), registeredNames, ps, outputField, 
works, methods, imports);
       case DECIMAL_SET_SCALE:
           return new DrillDecimalSetScaleFuncHolder(template.scope(), 
template.nulls(), template.isBinaryCommutative(),
                   template.isRandom(), registeredNames, ps, outputField, 
works, methods, imports);

Reply via email to