diff options
author | Volodymyr Vysotskyi <vvovyk@gmail.com> | 2018-07-12 19:00:48 +0300 |
---|---|---|
committer | Arina Ielchiieva <arina.yelchiyeva@gmail.com> | 2018-07-13 15:54:57 +0300 |
commit | c39ba74796d1f47887306ae81aa70ccf454effb3 (patch) | |
tree | 425b4b67849ca95b211dd41ba358f4b8ac27fbb2 /exec/vector | |
parent | eb90ebdfd6e40fe1769bfedd320fabc1e57c723b (diff) |
DRILL-6472: Prevent using zero precision in CAST function
- Add check for the correctness of scale value;
- Add check for fitting the value to the value with the concrete scale and precision;
- Implement negative UDF for VarDecimal
- Add unit tests for new checks and UDF.
Diffstat (limited to 'exec/vector')
-rw-r--r-- | exec/vector/src/main/java/org/apache/drill/exec/util/DecimalUtility.java | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/exec/vector/src/main/java/org/apache/drill/exec/util/DecimalUtility.java b/exec/vector/src/main/java/org/apache/drill/exec/util/DecimalUtility.java index 16ff0028d..5f2dade36 100644 --- a/exec/vector/src/main/java/org/apache/drill/exec/util/DecimalUtility.java +++ b/exec/vector/src/main/java/org/apache/drill/exec/util/DecimalUtility.java @@ -26,7 +26,10 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; +import org.apache.drill.common.exceptions.UserException; import org.apache.drill.common.types.TypeProtos; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @SuppressWarnings("WeakerAccess") public class DecimalUtility { @@ -37,6 +40,8 @@ public class DecimalUtility { public final static int DIGITS_BASE = 1000000000; public final static int INTEGER_SIZE = Integer.SIZE / 8; + private static final Logger logger = LoggerFactory.getLogger(DecimalUtility.class); + /** * Given the number of actual digits this function returns the * number of indexes it will occupy in the array of integers @@ -417,4 +422,22 @@ public class DecimalUtility { return defaultPrecision; } } + + /** + * Checks that the specified value may be fit into the value with specified + * {@code desiredPrecision} precision and {@code desiredScale} scale. + * Otherwise, the exception is thrown. + * + * @param value BigDecimal value to check + * @param desiredPrecision precision for the resulting value + * @param desiredScale scale for the resulting value + */ + public static void checkValueOverflow(BigDecimal value, int desiredPrecision, int desiredScale) { + if (value.precision() - value.scale() > desiredPrecision - desiredScale) { + throw UserException.validationError() + .message("Value %s overflows specified precision %s with scale %s.", + value, desiredPrecision, desiredScale) + .build(logger); + } + } } |