aboutsummaryrefslogtreecommitdiff
path: root/exec/vector
diff options
context:
space:
mode:
authorVolodymyr Vysotskyi <vvovyk@gmail.com>2018-07-12 19:00:48 +0300
committerArina Ielchiieva <arina.yelchiyeva@gmail.com>2018-07-13 15:54:57 +0300
commitc39ba74796d1f47887306ae81aa70ccf454effb3 (patch)
tree425b4b67849ca95b211dd41ba358f4b8ac27fbb2 /exec/vector
parenteb90ebdfd6e40fe1769bfedd320fabc1e57c723b (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.java23
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);
+ }
+ }
}