diff options
author | Volodymyr Vysotskyi <vvovyk@gmail.com> | 2018-08-27 23:16:35 -0700 |
---|---|---|
committer | Volodymyr Vysotskyi <vvovyk@gmail.com> | 2018-09-05 21:10:55 +0300 |
commit | fa0d78d16eaf35d30d95613913a5613b2a82280d (patch) | |
tree | 5ec5d5f7897d7a603b51e4985c64d250fc6d1e37 /exec/java-exec/src/main/java/org/apache/drill | |
parent | cc75188d0ce70f102786f69aa070255dd406ff3c (diff) |
DRILL-6710: Disallow negative scale for decimal data type
Diffstat (limited to 'exec/java-exec/src/main/java/org/apache/drill')
6 files changed, 18 insertions, 7 deletions
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/output/DecimalReturnTypeInference.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/output/DecimalReturnTypeInference.java index 442514f79..b30703d7b 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/output/DecimalReturnTypeInference.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/output/DecimalReturnTypeInference.java @@ -277,7 +277,7 @@ public class DecimalReturnTypeInference { return TypeProtos.MajorType.newBuilder() .setMinorType(attributes.getReturnValue().getType().getMinorType()) - .setScale(scale) + .setScale(Math.max(scale, 0)) .setPrecision(precision) .setMode(mode) .build(); diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionAddFunction.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionAddFunction.java index 138f97f63..db00c51a9 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionAddFunction.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionAddFunction.java @@ -31,6 +31,6 @@ public class DecimalScalePrecisionAddFunction extends DrillBaseComputeScalePreci outputPrecision = (outputScale + maxResultIntegerDigits); - checkPrecisionRange(); + adjustScaleAndPrecision(); } } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionDivideFunction.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionDivideFunction.java index eb79d44ae..af04f2bc8 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionDivideFunction.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionDivideFunction.java @@ -34,5 +34,6 @@ public class DecimalScalePrecisionDivideFunction extends DrillBaseComputeScalePr outputScale = Math.min(outputScale, MAX_NUMERIC_PRECISION - maxResultIntegerDigits); outputScale = Math.min(outputScale, DRILL_REL_DATATYPE_SYSTEM.getMaxNumericScale()); outputPrecision = maxResultIntegerDigits + outputScale; + adjustScaleAndPrecision(); } } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionModFunction.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionModFunction.java index 6901580eb..9508f3d4e 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionModFunction.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionModFunction.java @@ -38,7 +38,7 @@ public class DecimalScalePrecisionModFunction extends DrillBaseComputeScalePreci outputScale = outputPrecision - leftIntegerDigits; } - // Output precision should atleast be greater or equal to the input precision - outputPrecision = Math.max(outputPrecision, Math.max(leftPrecision, rightPrecision)); + // Output precision should at least be greater or equal to the input precision + outputPrecision = Math.min(outputPrecision, Math.max(leftPrecision, rightPrecision)); } } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionMulFunction.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionMulFunction.java index 2a8b22b9d..6cc553707 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionMulFunction.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DecimalScalePrecisionMulFunction.java @@ -32,10 +32,9 @@ public class DecimalScalePrecisionMulFunction extends DrillBaseComputeScalePreci public void computeScalePrecision(int leftPrecision, int leftScale, int rightPrecision, int rightScale) { // compute the output scale and precision here outputScale = leftScale + rightScale; - outputPrecision = leftPrecision + rightPrecision; - checkPrecisionRange(); + adjustScaleAndPrecision(); } } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DrillBaseComputeScalePrecision.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DrillBaseComputeScalePrecision.java index 1c3c18667..af671e01b 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DrillBaseComputeScalePrecision.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DrillBaseComputeScalePrecision.java @@ -17,9 +17,14 @@ */ package org.apache.drill.exec.planner.types.decimal; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import static org.apache.drill.exec.planner.types.DrillRelDataTypeSystem.DRILL_REL_DATATYPE_SYSTEM; public abstract class DrillBaseComputeScalePrecision { + private static final Logger logger = LoggerFactory.getLogger(DrillBaseComputeScalePrecision.class); + protected final static int MAX_NUMERIC_PRECISION = DRILL_REL_DATATYPE_SYSTEM.getMaxNumericPrecision(); protected int outputScale = 0; @@ -43,10 +48,16 @@ public abstract class DrillBaseComputeScalePrecision { * Cuts down the fractional part if the current precision * exceeds the maximum precision range. */ - protected void checkPrecisionRange() { + protected void adjustScaleAndPrecision() { if (outputPrecision > MAX_NUMERIC_PRECISION) { outputScale = outputScale - (outputPrecision - MAX_NUMERIC_PRECISION); outputPrecision = MAX_NUMERIC_PRECISION; } + if (outputScale < 0) { + logger.warn("Resulting precision: {} may overflow max allowed precision: {}.\n" + + "Forced setting max allowed precision and 0 scale.", + MAX_NUMERIC_PRECISION - outputScale, MAX_NUMERIC_PRECISION); + outputScale = 0; + } } } |