You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@drill.apache.org by GitBox <gi...@apache.org> on 2018/08/30 17:05:46 UTC

[GitHub] sohami closed pull request #1451: DRILL-6710: Disallow negative scale for VarDecimal

sohami closed pull request #1451: DRILL-6710: Disallow negative scale for VarDecimal
URL: https://github.com/apache/drill/pull/1451
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

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 da18cb11fde..c10ef853e7b 100644
--- a/exec/java-exec/src/main/codegen/templates/Decimal/DecimalFunctions.java
+++ b/exec/java-exec/src/main/codegen/templates/Decimal/DecimalFunctions.java
@@ -170,6 +170,8 @@ public void eval() {
               left.precision, left.scale,
               right.precision, right.scale);
 
+      // Do the verification of computed scale and precision here based on actual data
+      typeInference.verifyScaleAndPrecision();
       result.scale = typeInference.getOutputScale();
       result.precision = typeInference.getOutputPrecision();
 
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
index 2a94d9bf7c3..21caea7da8a 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
@@ -430,19 +430,25 @@ public LogicalExpression visitFunctionCall(FunctionCall call, FunctionLookupCont
           }
         }
 
-        FunctionHolderExpression funcExpr = matchedFuncHolder.getExpr(call.getName(), argsWithCast, call.getPosition());
-        MajorType funcExprMajorType = funcExpr.getMajorType();
-        if (DecimalUtility.isObsoleteDecimalType(funcExprMajorType.getMinorType())) {
-          MajorType majorType =
-              MajorType.newBuilder()
-                  .setMinorType(MinorType.VARDECIMAL)
-                  .setMode(funcExprMajorType.getMode())
-                  .setScale(funcExprMajorType.getScale())
-                  .setPrecision(funcExprMajorType.getPrecision())
-                  .build();
-          return addCastExpression(funcExpr, majorType, functionLookupContext, errorCollector);
+        try {
+          FunctionHolderExpression funcExpr = matchedFuncHolder.getExpr(call.getName(), argsWithCast, call.getPosition());
+          MajorType funcExprMajorType = funcExpr.getMajorType();
+          if (DecimalUtility.isObsoleteDecimalType(funcExprMajorType.getMinorType())) {
+            MajorType majorType = MajorType.newBuilder()
+              .setMinorType(MinorType.VARDECIMAL)
+              .setMode(funcExprMajorType.getMode())
+              .setScale(funcExprMajorType.getScale())
+              .setPrecision(funcExprMajorType.getPrecision())
+              .build();
+            return addCastExpression(funcExpr, majorType, functionLookupContext, errorCollector);
+          }
+          return funcExpr;
+        } catch (IllegalArgumentException ex) {
+          // this exception may be thrown while constructing FunctionHolderExpression when the return type has an
+          // invalid scale or precision
+          errorCollector.addGeneralError(call.getPosition(), ex.getMessage());
+          return NullExpression.INSTANCE;
         }
-        return funcExpr;
       }
 
       // as no drill func is found, search for a non-Drill function.
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 442514f792e..38a8e91d3e4 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
@@ -21,13 +21,15 @@
 import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.expression.ValueExpressions;
 import org.apache.drill.common.types.TypeProtos;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.fn.FunctionAttributes;
+import org.apache.drill.exec.expr.fn.FunctionUtils;
 import org.apache.drill.exec.planner.types.decimal.DecimalScalePrecisionAddFunction;
 import org.apache.drill.exec.planner.types.decimal.DecimalScalePrecisionDivideFunction;
 import org.apache.drill.exec.planner.types.decimal.DecimalScalePrecisionModFunction;
 import org.apache.drill.exec.planner.types.decimal.DecimalScalePrecisionMulFunction;
-import org.apache.drill.exec.expr.annotations.FunctionTemplate;
-import org.apache.drill.exec.expr.fn.FunctionAttributes;
-import org.apache.drill.exec.expr.fn.FunctionUtils;
+import org.apache.drill.exec.planner.types.decimal.DrillBaseComputeScalePrecision;
+import org.apache.drill.exec.planner.types.decimal.DrillUnaryComputeScalePrecision;
 import org.apache.drill.exec.util.DecimalUtility;
 
 import java.util.List;
@@ -35,7 +37,10 @@
 import static org.apache.drill.exec.planner.types.DrillRelDataTypeSystem.DRILL_REL_DATATYPE_SYSTEM;
 
 public class DecimalReturnTypeInference {
+  private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DecimalReturnTypeInference.class);
 
+  private static final String debugString = "Adjusted scale for this query is negative but it's an estimation during " +
+    "planning time. Actual validation will happen during execution based on real data. Estimated output scale: %d";
   /**
    * Return type calculation implementation for functions with return type set as
    * {@link org.apache.drill.exec.expr.annotations.FunctionTemplate.ReturnType#DECIMAL_ADD_SCALE}.
@@ -61,18 +66,23 @@
       TypeProtos.MajorType leftMajorType = logicalExpressions.get(0).getMajorType();
       TypeProtos.MajorType rightMajorType = logicalExpressions.get(1).getMajorType();
 
-      DecimalScalePrecisionAddFunction outputScalePrec =
+      final DrillBaseComputeScalePrecision outputScalePrec =
           new DecimalScalePrecisionAddFunction(
               DecimalUtility.getDefaultPrecision(leftMajorType.getMinorType(), leftMajorType.getPrecision()),
               leftMajorType.getScale(),
               DecimalUtility.getDefaultPrecision(rightMajorType.getMinorType(), rightMajorType.getPrecision()),
               rightMajorType.getScale());
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
+
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(TypeProtos.MinorType.VARDECIMAL)
-          .setScale(outputScalePrec.getOutputScale())
-          .setPrecision(outputScalePrec.getOutputPrecision())
-          .setMode(mode)
-          .build();
+        .setMinorType(TypeProtos.MinorType.VARDECIMAL)
+        .setScale(Math.max(outputScalePrec.getOutputScale(), 0))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(mode)
+        .build();
     }
   }
 
@@ -95,12 +105,18 @@
         precision = Math.max(precision, e.getMajorType().getPrecision());
       }
 
+      final DrillBaseComputeScalePrecision outputScalePrec = new DrillUnaryComputeScalePrecision(precision, scale);
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
+
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(attributes.getReturnValue().getType().getMinorType())
-          .setScale(scale)
-          .setPrecision(precision)
-          .setMode(TypeProtos.DataMode.OPTIONAL)
-          .build();
+        .setMinorType(attributes.getReturnValue().getType().getMinorType())
+        .setScale(Math.max(outputScalePrec.getOutputScale(), 0))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(TypeProtos.DataMode.OPTIONAL)
+        .build();
     }
   }
 
@@ -126,12 +142,19 @@
 
       int scale = ((ValueExpressions.IntExpression) logicalExpressions.get(logicalExpressions.size() - 1)).getInt();
       int precision = ((ValueExpressions.IntExpression) logicalExpressions.get(logicalExpressions.size() - 2)).getInt();
+
+      final DrillBaseComputeScalePrecision outputScalePrec = new DrillUnaryComputeScalePrecision(precision, scale);
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
+
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(attributes.getReturnValue().getType().getMinorType())
-          .setScale(scale)
-          .setPrecision(precision)
-          .setMode(mode)
-          .build();
+        .setMinorType(attributes.getReturnValue().getType().getMinorType())
+        .setScale(Math.max(outputScalePrec.getOutputScale(), 0))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(mode)
+        .build();
     }
   }
 
@@ -160,18 +183,23 @@
       TypeProtos.MajorType leftMajorType = logicalExpressions.get(0).getMajorType();
       TypeProtos.MajorType rightMajorType = logicalExpressions.get(1).getMajorType();
 
-      DecimalScalePrecisionDivideFunction outputScalePrec =
+      final DrillBaseComputeScalePrecision outputScalePrec =
           new DecimalScalePrecisionDivideFunction(
               DecimalUtility.getDefaultPrecision(leftMajorType.getMinorType(), leftMajorType.getPrecision()),
               leftMajorType.getScale(),
               DecimalUtility.getDefaultPrecision(rightMajorType.getMinorType(), rightMajorType.getPrecision()),
               rightMajorType.getScale());
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
+
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(TypeProtos.MinorType.VARDECIMAL)
-          .setScale(outputScalePrec.getOutputScale())
-          .setPrecision(outputScalePrec.getOutputPrecision())
-          .setMode(mode)
-          .build();
+        .setMinorType(TypeProtos.MinorType.VARDECIMAL)
+        .setScale(Math.max(outputScalePrec.getOutputScale(), 0))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(mode)
+        .build();
     }
   }
 
@@ -195,12 +223,18 @@
         precision = Math.max(precision, e.getMajorType().getPrecision());
       }
 
+      final DrillBaseComputeScalePrecision outputScalePrec = new DrillUnaryComputeScalePrecision(precision, scale);
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
+
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(attributes.getReturnValue().getType().getMinorType())
-          .setScale(scale)
-          .setPrecision(precision)
-          .setMode(mode)
-          .build();
+        .setMinorType(attributes.getReturnValue().getType().getMinorType())
+        .setScale(Math.max(outputScalePrec.getOutputScale(), 0))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(mode)
+        .build();
     }
   }
 
@@ -229,18 +263,23 @@
       TypeProtos.MajorType leftMajorType = logicalExpressions.get(0).getMajorType();
       TypeProtos.MajorType rightMajorType = logicalExpressions.get(1).getMajorType();
 
-      DecimalScalePrecisionModFunction outputScalePrec =
+      final DrillBaseComputeScalePrecision outputScalePrec =
           new DecimalScalePrecisionModFunction(
               DecimalUtility.getDefaultPrecision(leftMajorType.getMinorType(), leftMajorType.getPrecision()),
               leftMajorType.getScale(),
               DecimalUtility.getDefaultPrecision(rightMajorType.getMinorType(), rightMajorType.getPrecision()),
               rightMajorType.getScale());
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
+
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(TypeProtos.MinorType.VARDECIMAL)
-          .setScale(outputScalePrec.getOutputScale())
-          .setPrecision(outputScalePrec.getOutputPrecision())
-          .setMode(mode)
-          .build();
+        .setMinorType(TypeProtos.MinorType.VARDECIMAL)
+        .setScale(Math.max(outputScalePrec.getOutputScale(), 0))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(mode)
+        .build();
     }
   }
 
@@ -274,13 +313,18 @@
         // Get the scale from the second argument which should be a constant
         scale = ((ValueExpressions.IntExpression) logicalExpressions.get(1)).getInt();
       }
+      final DrillBaseComputeScalePrecision outputScalePrec = new DrillUnaryComputeScalePrecision(precision, scale);
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
 
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(attributes.getReturnValue().getType().getMinorType())
-          .setScale(scale)
-          .setPrecision(precision)
-          .setMode(mode)
-          .build();
+        .setMinorType(attributes.getReturnValue().getType().getMinorType())
+        .setScale(Math.max(outputScalePrec.getOutputScale(), 0))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(mode)
+        .build();
     }
   }
 
@@ -300,13 +344,19 @@
       for (LogicalExpression e : logicalExpressions) {
         scale = Math.max(scale, e.getMajorType().getScale());
       }
+      final DrillBaseComputeScalePrecision outputScalePrec = new DrillUnaryComputeScalePrecision(
+        DRILL_REL_DATATYPE_SYSTEM.getMaxNumericPrecision(), scale);
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
 
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(TypeProtos.MinorType.VARDECIMAL)
-          .setScale(scale)
-          .setPrecision(DRILL_REL_DATATYPE_SYSTEM.getMaxNumericPrecision())
-          .setMode(TypeProtos.DataMode.OPTIONAL)
-          .build();
+        .setMinorType(TypeProtos.MinorType.VARDECIMAL)
+        .setScale(Math.max(outputScalePrec.getOutputScale(), 0))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(TypeProtos.DataMode.OPTIONAL)
+        .build();
     }
   }
 
@@ -329,13 +379,19 @@
         scale = Math.max(scale, e.getMajorType().getScale());
       }
 
+      final DrillBaseComputeScalePrecision outputScalePrec = new DrillUnaryComputeScalePrecision
+        (DRILL_REL_DATATYPE_SYSTEM.getMaxNumericPrecision(), scale);
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
+
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(TypeProtos.MinorType.VARDECIMAL)
-          .setScale(Math.min(Math.max(6, scale),
-              DRILL_REL_DATATYPE_SYSTEM.getMaxNumericScale()))
-          .setPrecision(DRILL_REL_DATATYPE_SYSTEM.getMaxNumericPrecision())
-          .setMode(TypeProtos.DataMode.OPTIONAL)
-          .build();
+        .setMinorType(TypeProtos.MinorType.VARDECIMAL)
+        .setScale(Math.max(6, outputScalePrec.getOutputScale()))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(TypeProtos.DataMode.OPTIONAL)
+        .build();
     }
   }
 
@@ -357,18 +413,23 @@
       TypeProtos.MajorType leftMajorType = logicalExpressions.get(0).getMajorType();
       TypeProtos.MajorType rightMajorType = logicalExpressions.get(1).getMajorType();
 
-      DecimalScalePrecisionMulFunction outputScalePrec =
+      final DrillBaseComputeScalePrecision outputScalePrec =
           new DecimalScalePrecisionMulFunction(
               DecimalUtility.getDefaultPrecision(leftMajorType.getMinorType(), leftMajorType.getPrecision()),
               leftMajorType.getScale(),
               DecimalUtility.getDefaultPrecision(rightMajorType.getMinorType(), rightMajorType.getPrecision()),
               rightMajorType.getScale());
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
+
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(TypeProtos.MinorType.VARDECIMAL)
-          .setScale(outputScalePrec.getOutputScale())
-          .setPrecision(outputScalePrec.getOutputPrecision())
-          .setMode(mode)
-          .build();
+        .setMinorType(TypeProtos.MinorType.VARDECIMAL)
+        .setScale(Math.max(outputScalePrec.getOutputScale(), 0))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(mode)
+        .build();
     }
   }
 
@@ -404,12 +465,18 @@
         }
       }
 
+      final DrillBaseComputeScalePrecision outputScalePrec = new DrillUnaryComputeScalePrecision(precision, 0);
+
+      if (outputScalePrec.getOutputScale() < 0) {
+        logger.debug(debugString, outputScalePrec.getOutputScale());
+      }
+
       return TypeProtos.MajorType.newBuilder()
-          .setMinorType(attributes.getReturnValue().getType().getMinorType())
-          .setScale(0)
-          .setPrecision(precision)
-          .setMode(mode)
-          .build();
+        .setMinorType(attributes.getReturnValue().getType().getMinorType())
+        .setScale(Math.max(outputScalePrec.getOutputScale(), 0))
+        .setPrecision(outputScalePrec.getOutputPrecision())
+        .setMode(mode)
+        .build();
     }
   }
 }
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
index e3cd7e460db..cca888cad70 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
@@ -143,7 +143,7 @@ private static PhysicalPlan getQueryPlan(QueryContext context, String sql, Point
 
     try {
       return handler.getPlan(sqlNode);
-    } catch(ValidationException e) {
+    } catch(ValidationException | IllegalArgumentException e) {
       String errorMessage = e.getCause() != null ? e.getCause().getMessage() : e.getMessage();
       throw UserException.validationError(e)
           .message(errorMessage)
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 138f97f6387..5a4063d0938 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
@@ -17,7 +17,7 @@
  */
 package org.apache.drill.exec.planner.types.decimal;
 
-public class DecimalScalePrecisionAddFunction extends DrillBaseComputeScalePrecision {
+public class DecimalScalePrecisionAddFunction extends DrillBinaryComputeScalePrecision {
 
   public DecimalScalePrecisionAddFunction(int leftPrecision, int leftScale, int rightPrecision, int rightScale) {
     super(leftPrecision, leftScale, rightPrecision, rightScale);
@@ -28,9 +28,8 @@ public void computeScalePrecision(int leftPrecision, int leftScale, int rightPre
     // compute the output scale and precision here
     outputScale = Math.max(leftScale, rightScale);
     int maxResultIntegerDigits = Math.max((leftPrecision - leftScale), (rightPrecision - rightScale)) + 1;
-
     outputPrecision = (outputScale + maxResultIntegerDigits);
 
-    checkPrecisionRange();
+    super.computeScalePrecision(leftPrecision, leftScale, rightPrecision, rightScale);
   }
 }
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 eb79d44ae0a..c3043cb93a0 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
@@ -19,7 +19,7 @@
 
 import static org.apache.drill.exec.planner.types.DrillRelDataTypeSystem.DRILL_REL_DATATYPE_SYSTEM;
 
-public class DecimalScalePrecisionDivideFunction extends DrillBaseComputeScalePrecision {
+public class DecimalScalePrecisionDivideFunction extends DrillBinaryComputeScalePrecision {
 
   public DecimalScalePrecisionDivideFunction(int leftPrecision, int leftScale, int rightPrecision, int rightScale) {
     super(leftPrecision, leftScale, rightPrecision, rightScale);
@@ -34,5 +34,6 @@ public void computeScalePrecision(int leftPrecision, int leftScale, int rightPre
     outputScale = Math.min(outputScale, MAX_NUMERIC_PRECISION - maxResultIntegerDigits);
     outputScale = Math.min(outputScale, DRILL_REL_DATATYPE_SYSTEM.getMaxNumericScale());
     outputPrecision = maxResultIntegerDigits + outputScale;
+    super.computeScalePrecision(leftPrecision, leftScale, rightPrecision, rightScale);
   }
 }
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 6901580eb26..ae39b329ebe 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
@@ -19,7 +19,7 @@
 
 import static org.apache.drill.exec.planner.types.DrillRelDataTypeSystem.DRILL_REL_DATATYPE_SYSTEM;
 
-public class DecimalScalePrecisionModFunction extends DrillBaseComputeScalePrecision {
+public class DecimalScalePrecisionModFunction extends DrillBinaryComputeScalePrecision {
 
   public DecimalScalePrecisionModFunction(int leftPrecision, int leftScale, int rightPrecision, int rightScale) {
     super(leftPrecision, leftScale, rightPrecision, rightScale);
@@ -40,5 +40,6 @@ public void computeScalePrecision(int leftPrecision, int leftScale, int rightPre
 
     // Output precision should atleast be greater or equal to the input precision
     outputPrecision = Math.max(outputPrecision, Math.max(leftPrecision, rightPrecision));
+    super.computeScalePrecision(leftPrecision, leftScale, rightPrecision, rightScale);
   }
 }
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 2a8b22b9d39..55db369335b 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
@@ -22,7 +22,7 @@
  * We simply add the input scale and precision to determine the output's scale
  * and precision
  */
-public class DecimalScalePrecisionMulFunction extends DrillBaseComputeScalePrecision {
+public class DecimalScalePrecisionMulFunction extends DrillBinaryComputeScalePrecision {
 
   public DecimalScalePrecisionMulFunction(int leftPrecision, int leftScale, int rightPrecision, int rightScale) {
     super(leftPrecision, leftScale, rightPrecision, rightScale);
@@ -32,10 +32,8 @@ public DecimalScalePrecisionMulFunction(int leftPrecision, int leftScale, int ri
   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();
+    super.computeScalePrecision(leftPrecision, leftScale, rightPrecision, rightScale);
   }
 }
 
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 1c3c186670b..c59450c9c79 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
@@ -21,16 +21,11 @@
 
 public abstract class DrillBaseComputeScalePrecision {
   protected final static int MAX_NUMERIC_PRECISION = DRILL_REL_DATATYPE_SYSTEM.getMaxNumericPrecision();
+  protected final static int MAX_NUMERIC_SCALE = DRILL_REL_DATATYPE_SYSTEM.getMaxNumericScale();
 
   protected int outputScale = 0;
   protected int outputPrecision = 0;
 
-  public DrillBaseComputeScalePrecision(int leftPrecision, int leftScale, int rightPrecision, int rightScale) {
-    computeScalePrecision(leftPrecision, leftScale, rightPrecision, rightScale);
-  }
-
-  public abstract void computeScalePrecision(int leftPrecision, int leftScale, int rightPrecision, int rightScale);
-
   public int getOutputScale() {
     return outputScale;
   }
@@ -43,10 +38,25 @@ public int getOutputPrecision() {
    * Cuts down the fractional part if the current precision
    * exceeds the maximum precision range.
    */
-  protected void checkPrecisionRange() {
+  public void adjustPrecisionRange() {
     if (outputPrecision > MAX_NUMERIC_PRECISION) {
       outputScale = outputScale - (outputPrecision - MAX_NUMERIC_PRECISION);
       outputPrecision = MAX_NUMERIC_PRECISION;
     }
   }
+
+  /**
+   * Verifies if output scale and precision are valid or not
+   */
+  public void verifyScaleAndPrecision() {
+    if (outputScale > outputPrecision) {
+      throw new IllegalArgumentException(String.format("The output of this operation on decimal type is invalid as " +
+          "computed scale is greater than precision. [Output expression precision: %d and scale: %d]",
+        outputPrecision, outputScale));
+    } else if (outputScale < 0 || outputPrecision > MAX_NUMERIC_PRECISION || outputScale > MAX_NUMERIC_SCALE) {
+      throw new IllegalArgumentException(String.format("The output of this operation on decimal type is out of range." +
+        " Drill supports max precision of %d and non-negative maximum scale %d. [Output expression precision: %d and " +
+          "scale: %d]", MAX_NUMERIC_PRECISION, MAX_NUMERIC_SCALE, outputPrecision, outputScale));
+    }
+  }
 }
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DrillBinaryComputeScalePrecision.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DrillBinaryComputeScalePrecision.java
new file mode 100644
index 00000000000..7f6eea271df
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DrillBinaryComputeScalePrecision.java
@@ -0,0 +1,29 @@
+/*
+ * 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.planner.types.decimal;
+
+public abstract class DrillBinaryComputeScalePrecision extends DrillBaseComputeScalePrecision {
+
+  public DrillBinaryComputeScalePrecision(int leftPrecision, int leftScale, int rightPrecision, int rightScale) {
+    computeScalePrecision(leftPrecision, leftScale, rightPrecision, rightScale);
+  }
+
+  public void computeScalePrecision(int leftPrecision, int leftScale, int rightPrecision, int rightScale) {
+    adjustPrecisionRange();
+  }
+}
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DrillUnaryComputeScalePrecision.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DrillUnaryComputeScalePrecision.java
new file mode 100644
index 00000000000..c39a21551c0
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/decimal/DrillUnaryComputeScalePrecision.java
@@ -0,0 +1,27 @@
+/*
+ * 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.planner.types.decimal;
+
+public class DrillUnaryComputeScalePrecision extends DrillBaseComputeScalePrecision {
+
+  public DrillUnaryComputeScalePrecision(int precision, int scale) {
+    outputPrecision = precision;
+    outputScale = scale;
+    adjustPrecisionRange();
+  }
+}
diff --git a/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsQuery.java b/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsQuery.java
index 390a6bf8f33..1f0f7a36040 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsQuery.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsQuery.java
@@ -17,22 +17,26 @@
  */
 package org.apache.drill;
 
-import static org.apache.drill.exec.expr.fn.impl.DateUtility.formatTimeStamp;
-
-import java.math.BigDecimal;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-
 import org.apache.drill.categories.SqlFunctionTest;
+import org.apache.drill.common.exceptions.UserRemoteException;
 import org.apache.drill.exec.planner.physical.PlannerSettings;
 import org.apache.drill.test.BaseTestQuery;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
+import org.junit.rules.ExpectedException;
+
+import java.math.BigDecimal;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+
+import static org.apache.drill.exec.expr.fn.impl.DateUtility.formatTimeStamp;
+import static org.hamcrest.CoreMatchers.containsString;
 
 @Category(SqlFunctionTest.class)
 public class TestFunctionsQuery extends BaseTestQuery {
@@ -48,6 +52,9 @@ public static void disableDecimalDataType() {
     resetSessionOption(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
   }
 
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
   @Test
   public void testAbsDecimalFunction() throws Exception{
     String query = "SELECT " +
@@ -58,16 +65,18 @@ public void testAbsDecimalFunction() throws Exception{
         "abs(cast('12345678912345678912.4567' as decimal(28, 5))) DEC28_ABS_1, " +
         "abs(cast('-12345678912345678912.4567' as decimal(28, 5))) DEC28_ABS_2, " +
         "abs(cast('1234567891234567891234567891234567891.4' as decimal(38, 1))) DEC38_ABS_1, " +
-        "abs(cast('-1234567891234567891234567891234567891.4' as decimal(38, 1))) DEC38_ABS_2 " +
-        "FROM cp.`tpch/region.parquet` limit 1";
+        "abs(cast('-1234567891234567891234567891234567891.4' as decimal(38, 1))) DEC38_ABS_2";
 
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
-        .baselineColumns("DEC9_ABS_1", "DEC9_ABS_2", "DEC18_ABS_1", "DEC18_ABS_2", "DEC28_ABS_1", "DEC28_ABS_2", "DEC38_ABS_1", "DEC38_ABS_2")
-        .baselineValues(new BigDecimal("1234.45670"), new BigDecimal("1234.45670"), new BigDecimal("99999912399.45670"), new BigDecimal("99999912399.45670"),
-            new BigDecimal("12345678912345678912.45670"), new BigDecimal("12345678912345678912.45670"), new BigDecimal("1234567891234567891234567891234567891.4"),
-            new BigDecimal("1234567891234567891234567891234567891.4"))
+        .baselineColumns("DEC9_ABS_1", "DEC9_ABS_2", "DEC18_ABS_1", "DEC18_ABS_2", "DEC28_ABS_1", "DEC28_ABS_2",
+          "DEC38_ABS_1", "DEC38_ABS_2")
+        .baselineValues(new BigDecimal("1234.45670"), new BigDecimal("1234.45670"),
+          new BigDecimal("99999912399.45670"), new BigDecimal("99999912399.45670"),
+          new BigDecimal("12345678912345678912.45670"), new BigDecimal("12345678912345678912.45670"),
+          new BigDecimal("1234567891234567891234567891234567891.4"),
+          new BigDecimal("1234567891234567891234567891234567891.4"))
         .go();
   }
 
@@ -92,20 +101,23 @@ public void testCeilDecimalFunction() throws Exception {
         "ceil(cast('999999999999999999999999999999999999.4' as decimal(38, 1))) DEC38_2, " +
         "ceil(cast('1234567891234567891234567891234567891.0' as decimal(38, 1))) DEC38_3, " +
         "ceil(cast('-1234567891234567891234567891234567891.4' as decimal(38, 1))) DEC38_4, " +
-        "ceil(cast('-1234567891234567891234567891234567891.0' as decimal(38, 1))) DEC38_5 " +
-        "FROM cp.`tpch/region.parquet` limit 1";
+        "ceil(cast('-1234567891234567891234567891234567891.0' as decimal(38, 1))) DEC38_5";
 
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
         .baselineColumns("DEC9_1", "DEC9_2", "DEC9_3", "DEC9_4", "DEC18_1", "DEC18_2", "DEC18_3", "DEC18_4", "DEC28_1",
             "DEC28_2", "DEC28_3", "DEC28_4", "DEC28_5", "DEC38_1", "DEC38_2", "DEC38_3", "DEC38_4", "DEC38_5")
-        .baselineValues(new BigDecimal("1235"), new BigDecimal("1234"), new BigDecimal("-1234"), new BigDecimal("-1234"),
-            new BigDecimal("99999912400"), new BigDecimal("99999912399"), new BigDecimal("-99999912399"), new BigDecimal("-99999912399"),
-            new BigDecimal("12345678912345678913"), new BigDecimal("1000000000000000000"), new BigDecimal("12345678912345678912"), new BigDecimal("-12345678912345678912"),
-            new BigDecimal("-12345678912345678912"), new BigDecimal("1234567891234567891234567891234567892"), new BigDecimal("1000000000000000000000000000000000000"),
-            new BigDecimal("1234567891234567891234567891234567891"), new BigDecimal("-1234567891234567891234567891234567891"),
-            new BigDecimal("-1234567891234567891234567891234567891"))
+        .baselineValues(new BigDecimal("1235"), new BigDecimal("1234"), new BigDecimal("-1234"),
+          new BigDecimal("-1234"), new BigDecimal("99999912400"), new BigDecimal("99999912399"),
+          new BigDecimal("-99999912399"), new BigDecimal("-99999912399"),
+          new BigDecimal("12345678912345678913"), new BigDecimal("1000000000000000000"),
+          new BigDecimal("12345678912345678912"), new BigDecimal("-12345678912345678912"),
+          new BigDecimal("-12345678912345678912"), new BigDecimal("1234567891234567891234567891234567892"),
+          new BigDecimal("1000000000000000000000000000000000000"),
+          new BigDecimal("1234567891234567891234567891234567891"),
+          new BigDecimal("-1234567891234567891234567891234567891"),
+          new BigDecimal("-1234567891234567891234567891234567891"))
         .go();
   }
 
@@ -129,20 +141,23 @@ public void testFloorDecimalFunction() throws Exception {
         "floor(cast('999999999999999999999999999999999999.4' as decimal(38, 1))) DEC38_2, " +
         "floor(cast('1234567891234567891234567891234567891.0' as decimal(38, 1))) DEC38_3, " +
         "floor(cast('-1234567891234567891234567891234567891.4' as decimal(38, 1))) DEC38_4, " +
-        "floor(cast('-999999999999999999999999999999999999.4' as decimal(38, 1))) DEC38_5 " +
-        "FROM cp.`tpch/region.parquet` limit 1";
+        "floor(cast('-999999999999999999999999999999999999.4' as decimal(38, 1))) DEC38_5";
 
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
         .baselineColumns("DEC9_1", "DEC9_2", "DEC9_3", "DEC9_4", "DEC18_1", "DEC18_2", "DEC18_3", "DEC18_4", "DEC28_1",
             "DEC28_2", "DEC28_3", "DEC28_4", "DEC28_5", "DEC38_1", "DEC38_2", "DEC38_3", "DEC38_4", "DEC38_5")
-        .baselineValues(new BigDecimal("1234"), new BigDecimal("1234"), new BigDecimal("-1235"), new BigDecimal("-1234"),
-            new BigDecimal("99999912399"), new BigDecimal("99999912399"), new BigDecimal("-99999912400"), new BigDecimal("-99999912399"),
-            new BigDecimal("12345678912345678912"), new BigDecimal("999999999999999999"), new BigDecimal("12345678912345678912"),
-            new BigDecimal("-12345678912345678913"), new BigDecimal("-12345678912345678912"), new BigDecimal("1234567891234567891234567891234567891"),
-            new BigDecimal("999999999999999999999999999999999999"), new BigDecimal("1234567891234567891234567891234567891"),
-            new BigDecimal("-1234567891234567891234567891234567892"), new BigDecimal("-1000000000000000000000000000000000000"))
+        .baselineValues(new BigDecimal("1234"), new BigDecimal("1234"), new BigDecimal("-1235"),
+          new BigDecimal("-1234"), new BigDecimal("99999912399"), new BigDecimal("99999912399"),
+          new BigDecimal("-99999912400"), new BigDecimal("-99999912399"),
+          new BigDecimal("12345678912345678912"), new BigDecimal("999999999999999999"),
+          new BigDecimal("12345678912345678912"), new BigDecimal("-12345678912345678913"),
+          new BigDecimal("-12345678912345678912"), new BigDecimal("1234567891234567891234567891234567891"),
+          new BigDecimal("999999999999999999999999999999999999"),
+          new BigDecimal("1234567891234567891234567891234567891"),
+          new BigDecimal("-1234567891234567891234567891234567892"),
+          new BigDecimal("-1000000000000000000000000000000000000"))
         .go();
   }
 
@@ -166,21 +181,23 @@ public void testTruncateDecimalFunction() throws Exception {
         "trunc(cast('999999999999999999999999999999999999.4' as decimal(38, 1))) DEC38_2, " +
         "trunc(cast('1234567891234567891234567891234567891.0' as decimal(38, 1))) DEC38_3, " +
         "trunc(cast('-1234567891234567891234567891234567891.4' as decimal(38, 1))) DEC38_4, " +
-        "trunc(cast('-999999999999999999999999999999999999.4' as decimal(38, 1))) DEC38_5 " +
-        "FROM cp.`tpch/region.parquet` limit 1";
+        "trunc(cast('-999999999999999999999999999999999999.4' as decimal(38, 1))) DEC38_5";
 
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
         .baselineColumns("DEC9_1", "DEC9_2", "DEC9_3", "DEC9_4", "DEC18_1", "DEC18_2", "DEC18_3", "DEC18_4", "DEC28_1",
             "DEC28_2", "DEC28_3", "DEC28_4", "DEC28_5", "DEC38_1", "DEC38_2", "DEC38_3", "DEC38_4", "DEC38_5")
-        .baselineValues(new BigDecimal("1234"), new BigDecimal("1234"), new BigDecimal("-1234"), new BigDecimal("0"),
-            new BigDecimal("99999912399"), new BigDecimal("99999912399"), new BigDecimal("-99999912399"),
-            new BigDecimal("-99999912399"), new BigDecimal("12345678912345678912"), new BigDecimal("999999999999999999"),
-            new BigDecimal("12345678912345678912"), new BigDecimal("-12345678912345678912"), new BigDecimal("-12345678912345678912"),
-            new BigDecimal("1234567891234567891234567891234567891"), new BigDecimal("999999999999999999999999999999999999"),
-            new BigDecimal("1234567891234567891234567891234567891"), new BigDecimal("-1234567891234567891234567891234567891"),
-            new BigDecimal("-999999999999999999999999999999999999"))
+        .baselineValues(new BigDecimal("1234"), new BigDecimal("1234"), new BigDecimal("-1234"),
+          new BigDecimal("0"), new BigDecimal("99999912399"), new BigDecimal("99999912399"),
+          new BigDecimal("-99999912399"), new BigDecimal("-99999912399"),
+          new BigDecimal("12345678912345678912"), new BigDecimal("999999999999999999"),
+          new BigDecimal("12345678912345678912"), new BigDecimal("-12345678912345678912"),
+          new BigDecimal("-12345678912345678912"), new BigDecimal("1234567891234567891234567891234567891"),
+          new BigDecimal("999999999999999999999999999999999999"),
+          new BigDecimal("1234567891234567891234567891234567891"),
+          new BigDecimal("-1234567891234567891234567891234567891"),
+          new BigDecimal("-999999999999999999999999999999999999"))
         .go();
   }
 
@@ -204,20 +221,22 @@ public void testTruncateWithParamDecimalFunction() throws Exception {
         "trunc(cast('999999999.4' as decimal(38, 1)), 8) DEC38_2, " +
         "trunc(cast('999999999.1234' as decimal(38, 4)), 12) DEC38_3, " +
         "trunc(cast('-123456789123456789.4' as decimal(38, 1)), 10) DEC38_4, " +
-        "trunc(cast('-999999999999999999999999999999999999.4' as decimal(38, 1)), 1) DEC38_5 " +
-        "FROM cp.`tpch/region.parquet` limit 1";
+        "trunc(cast('-999999999999999999999999999999999999.4' as decimal(38, 1)), 1) DEC38_5";
 
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
         .baselineColumns("DEC9_1", "DEC9_2", "DEC9_3", "DEC9_4", "DEC18_1", "DEC18_2", "DEC18_3", "DEC18_4", "DEC28_1",
             "DEC28_2", "DEC28_3", "DEC28_4", "DEC28_5", "DEC38_1", "DEC38_2", "DEC38_3", "DEC38_4", "DEC38_5")
-        .baselineValues(new BigDecimal("1234.45"), new BigDecimal("1234.4500"), new BigDecimal("-1234"), new BigDecimal("0.11"),
-            new BigDecimal("99999912399.45"), new BigDecimal("99999912399.00"), new BigDecimal("-99999912399.450000"),
-            new BigDecimal("-99999912399.0000"), new BigDecimal("12345678912345678912.4"), new BigDecimal("999999999999999999.456000"),
-            new BigDecimal("12345678912345678912.00"), new BigDecimal("-12345678912345678912"), new BigDecimal("-12345678912345678912.0"),
-            new BigDecimal("999999999.1234567"), new BigDecimal("999999999.40000000"), new BigDecimal("999999999.123400000000"),
-            new BigDecimal("-123456789123456789.4000000000"), new BigDecimal("-999999999999999999999999999999999999.4"))
+        .baselineValues(new BigDecimal("1234.45"), new BigDecimal("1234.4500"), new BigDecimal("-1234"),
+          new BigDecimal("0.11"), new BigDecimal("99999912399.45"), new BigDecimal("99999912399.00"),
+          new BigDecimal("-99999912399.450000"), new BigDecimal("-99999912399.0000"),
+          new BigDecimal("12345678912345678912.4"), new BigDecimal("999999999999999999.456000"),
+          new BigDecimal("12345678912345678912.00"), new BigDecimal("-12345678912345678912"),
+          new BigDecimal("-12345678912345678912.0"), new BigDecimal("999999999.1234567"),
+          new BigDecimal("999999999.40000000"), new BigDecimal("999999999.123400000000"),
+          new BigDecimal("-123456789123456789.4000000000"),
+          new BigDecimal("-999999999999999999999999999999999999.4"))
         .go();
   }
 
@@ -242,20 +261,23 @@ public void testRoundDecimalFunction() throws Exception {
         "round(cast('999999999999999999999999999999999999.5' as decimal(38, 1))) DEC38_3, " +
         "round(cast('1234567891234567891234567891234567891.2' as decimal(38, 1))) DEC38_4, " +
         "round(cast('-1234567891234567891234567891234567891.4' as decimal(38, 1))) DEC38_5, " +
-        "round(cast('-999999999999999999999999999999999999.9' as decimal(38, 1))) DEC38_6 " +
-        "FROM cp.`tpch/region.parquet` limit 1";
+        "round(cast('-999999999999999999999999999999999999.9' as decimal(38, 1))) DEC38_6";
 
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
         .baselineColumns("DEC9_1", "DEC9_2", "DEC9_3", "DEC9_4", "DEC18_1", "DEC18_2", "DEC18_3", "DEC18_4", "DEC28_1",
             "DEC28_2", "DEC28_3", "DEC28_4", "DEC28_5", "DEC38_1", "DEC38_2", "DEC38_3", "DEC38_4", "DEC38_5", "DEC38_6")
-        .baselineValues(new BigDecimal("1235"), new BigDecimal("1234"), new BigDecimal("-1235"), new BigDecimal("-1234"),
-            new BigDecimal("99999912400"), new BigDecimal("99999912399"), new BigDecimal("-99999912400"), new BigDecimal("-99999912399"),
-            new BigDecimal("12345678912345678913"), new BigDecimal("1000000000000000000"), new BigDecimal("12345678912345678912"),
-            new BigDecimal("-12345678912345678913"), new BigDecimal("-12345678912345678912"), new BigDecimal("1000000000000000000000000000"),
-            new BigDecimal("100000000"), new BigDecimal("1000000000000000000000000000000000000"), new BigDecimal("1234567891234567891234567891234567891"),
-            new BigDecimal("-1234567891234567891234567891234567891"), new BigDecimal("-1000000000000000000000000000000000000"))
+        .baselineValues(new BigDecimal("1235"), new BigDecimal("1234"), new BigDecimal("-1235"),
+          new BigDecimal("-1234"), new BigDecimal("99999912400"), new BigDecimal("99999912399"),
+          new BigDecimal("-99999912400"), new BigDecimal("-99999912399"),
+          new BigDecimal("12345678912345678913"), new BigDecimal("1000000000000000000"),
+          new BigDecimal("12345678912345678912"), new BigDecimal("-12345678912345678913"),
+          new BigDecimal("-12345678912345678912"), new BigDecimal("1000000000000000000000000000"),
+          new BigDecimal("100000000"), new BigDecimal("1000000000000000000000000000000000000"),
+          new BigDecimal("1234567891234567891234567891234567891"),
+          new BigDecimal("-1234567891234567891234567891234567891"),
+          new BigDecimal("-1000000000000000000000000000000000000"))
         .go();
   }
 
@@ -283,20 +305,24 @@ public void testRoundWithScaleDecimalFunction() throws Exception {
         "round(cast('999999999.9999999995678' as decimal(38, 18)), 11) DEC38_4, " +
         "round(cast('999999999.9999999995678' as decimal(38, 18)), 21) DEC38_5, " +
         "round(cast('-1234567891234567891234567891234567891.4' as decimal(38, 1)), 1) DEC38_6, " +
-        "round(cast('-999999999999999999999999999999999999.9' as decimal(38, 1)), 0) DEC38_7 " +
-        "FROM cp.`tpch/region.parquet` limit 1";
+        "round(cast('-999999999999999999999999999999999999.9' as decimal(38, 1)), 0) DEC38_7";
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
-        .baselineColumns("DEC9_1", "DEC9_2", "DEC9_3", "DEC9_4", "DEC9_5", "DEC18_1", "DEC18_2", "DEC18_3", "DEC18_4", "DEC28_1",
-            "DEC28_2", "DEC28_3", "DEC28_4", "DEC28_5", "DEC38_1", "DEC38_2", "DEC38_3", "DEC38_4", "DEC38_5", "DEC38_6", "DEC38_7")
-        .baselineValues(new BigDecimal("1234.557"), new BigDecimal("1234.10"), new BigDecimal("-1234.5567"), new BigDecimal("-1234.123"),
-            new BigDecimal("-1234.1200"), new BigDecimal("99999912399.957"), new BigDecimal("99999912399.00"), new BigDecimal("-99999912399.56"),
-            new BigDecimal("-99999912399"), new BigDecimal("12345678912345678912.56"), new BigDecimal("999999999999999999.6"),
-            new BigDecimal("12345678912345678912.00000000"), new BigDecimal("-12345678912345678912.557"), new BigDecimal("-12345678912345678912"),
-            new BigDecimal("999999999999999999999999999.5"), new BigDecimal("99999999.512345679"), new BigDecimal("1000000000.000000000"),
-            new BigDecimal("999999999.99999999957"), new BigDecimal("999999999.999999999567800000000"), new BigDecimal("-1234567891234567891234567891234567891.4"),
-            new BigDecimal("-1000000000000000000000000000000000000"))
+        .baselineColumns("DEC9_1", "DEC9_2", "DEC9_3", "DEC9_4", "DEC9_5", "DEC18_1", "DEC18_2", "DEC18_3", "DEC18_4",
+          "DEC28_1", "DEC28_2", "DEC28_3", "DEC28_4", "DEC28_5", "DEC38_1", "DEC38_2", "DEC38_3", "DEC38_4", "DEC38_5",
+          "DEC38_6", "DEC38_7")
+        .baselineValues(new BigDecimal("1234.557"), new BigDecimal("1234.10"), new BigDecimal("-1234.5567"),
+          new BigDecimal("-1234.123"), new BigDecimal("-1234.1200"), new BigDecimal("99999912399.957"),
+          new BigDecimal("99999912399.00"), new BigDecimal("-99999912399.56"),
+          new BigDecimal("-99999912399"), new BigDecimal("12345678912345678912.56"),
+          new BigDecimal("999999999999999999.6"), new BigDecimal("12345678912345678912.00000000"),
+          new BigDecimal("-12345678912345678912.557"), new BigDecimal("-12345678912345678912"),
+          new BigDecimal("999999999999999999999999999.5"), new BigDecimal("99999999.512345679"),
+          new BigDecimal("1000000000.000000000"), new BigDecimal("999999999.99999999957"),
+          new BigDecimal("999999999.999999999567800000000"),
+          new BigDecimal("-1234567891234567891234567891234567891.4"),
+          new BigDecimal("-1000000000000000000000000000000000000"))
         .go();
   }
 
@@ -305,8 +331,7 @@ public void testRoundWithScaleDecimalFunction() throws Exception {
   public void testCastDecimalDivide() throws Exception {
     String query = "select  (cast('9' as decimal(9, 1)) / cast('2' as decimal(4, 1))) as DEC9_DIV, " +
         "cast('999999999' as decimal(9,0)) / cast('0.000000000000000000000000001' as decimal(28,28)) as DEC38_DIV, " +
-        "cast('123456789.123456789' as decimal(18, 9)) * cast('123456789.123456789' as decimal(18, 9)) as DEC18_MUL " +
-        "from cp.`employee.json` where employee_id = 1";
+        "cast('123456789.123456789' as decimal(18, 9)) * cast('123456789.123456789' as decimal(18, 9)) as DEC18_MUL";
 
     testBuilder()
         .sqlQuery(query)
@@ -327,8 +352,7 @@ public void testCastDecimalDivide() throws Exception {
   @Test
   public void testLiteralCastToFLOATYieldsFLOAT() throws Exception {
     testBuilder()
-    .sqlQuery( "SELECT CAST( 1.5 AS FLOAT ) AS ShouldBeFLOAT "
-               + "FROM cp.`employee.json` LIMIT 1" )
+    .sqlQuery( "SELECT CAST( 1.5 AS FLOAT ) AS ShouldBeFLOAT")
     .unOrdered()
     .baselineColumns("ShouldBeFLOAT")
     .baselineValues(Float.valueOf(1.5f))
@@ -338,8 +362,7 @@ public void testLiteralCastToFLOATYieldsFLOAT() throws Exception {
   @Test
   public void testLiteralCastToDOUBLEYieldsDOUBLE() throws Exception {
     testBuilder()
-    .sqlQuery( "SELECT CAST( 1.25 AS DOUBLE PRECISION ) AS ShouldBeDOUBLE "
-               + "FROM cp.`employee.json` LIMIT 1" )
+    .sqlQuery( "SELECT CAST( 1.25 AS DOUBLE PRECISION ) AS ShouldBeDOUBLE")
     .unOrdered()
     .baselineColumns("ShouldBeDOUBLE")
     .baselineValues(Double.valueOf(1.25))
@@ -349,8 +372,7 @@ public void testLiteralCastToDOUBLEYieldsDOUBLE() throws Exception {
   @Test
   public void testLiteralCastToBIGINTYieldsBIGINT() throws Exception {
     testBuilder()
-    .sqlQuery( "SELECT CAST( 64 AS BIGINT ) AS ShouldBeBIGINT "
-               + "FROM cp.`employee.json` LIMIT 1" )
+    .sqlQuery( "SELECT CAST( 64 AS BIGINT ) AS ShouldBeBIGINT")
     .unOrdered()
     .baselineColumns("ShouldBeBIGINT")
     .baselineValues(Long.valueOf(64))
@@ -360,8 +382,7 @@ public void testLiteralCastToBIGINTYieldsBIGINT() throws Exception {
   @Test
   public void testLiteralCastToINTEGERYieldsINTEGER() throws Exception {
     testBuilder()
-    .sqlQuery( "SELECT CAST( 32 AS INTEGER ) AS ShouldBeINTEGER "
-               + "FROM cp.`employee.json` LIMIT 1" )
+    .sqlQuery( "SELECT CAST( 32 AS INTEGER ) AS ShouldBeINTEGER")
     .unOrdered()
     .baselineColumns("ShouldBeINTEGER")
     .baselineValues(Integer.valueOf(32))
@@ -372,8 +393,7 @@ public void testLiteralCastToINTEGERYieldsINTEGER() throws Exception {
   @Test
   public void testLiteralCastToSMALLINTYieldsSMALLINT() throws Exception {
     testBuilder()
-    .sqlQuery( "SELECT CAST( 16 AS SMALLINT ) AS ShouldBeSMALLINT "
-               + "FROM cp.`employee.json` LIMIT 1" )
+    .sqlQuery( "SELECT CAST( 16 AS SMALLINT ) AS ShouldBeSMALLINT")
     .unOrdered()
     .baselineColumns("ShouldBeSMALLINT")
     .baselineValues(Short.valueOf((short) 16))
@@ -384,8 +404,7 @@ public void testLiteralCastToSMALLINTYieldsSMALLINT() throws Exception {
   @Test
   public void testLiteralCastToTINYINTYieldsTINYINT() throws Exception {
     testBuilder()
-    .sqlQuery( "SELECT CAST( 8 AS TINYINT ) AS ShouldBeTINYINT "
-               + "FROM cp.`employee.json` LIMIT 1" )
+    .sqlQuery( "SELECT CAST( 8 AS TINYINT ) AS ShouldBeTINYINT")
     .unOrdered()
     .baselineColumns("ShouldBeTINYINT")
     .baselineValues(Byte.valueOf((byte) 8))
@@ -394,17 +413,27 @@ public void testLiteralCastToTINYINTYieldsTINYINT() throws Exception {
 
 
   @Test
-  public void testDecimalMultiplicationOverflowHandling() throws Exception {
-    String query = "select cast('1' as decimal(9, 5)) * cast ('999999999999999999999999999.999999999' as decimal(38, 9)) as DEC38_1, " +
-        "cast('1000000000000000001.000000000000000000' as decimal(38, 18)) * cast('0.999999999999999999' as decimal(38, 18)) as DEC38_2, " +
-        "cast('3' as decimal(9, 8)) * cast ('333333333.3333333333333333333' as decimal(38, 19)) as DEC38_3 " +
-        "from cp.`employee.json` where employee_id = 1";
+  public void testDecimalMultiplicationOverflowNegativeScale() throws Exception {
+    String query = "select cast('1000000000000000001.000000000000000000' as decimal(38, 18)) * " +
+      "cast('0.999999999999999999' as decimal(38, 18)) as DEC38_1";
+    expectedException.expect(UserRemoteException.class);
+    expectedException.expectMessage(containsString("SYSTEM ERROR"));
+    expectedException.expectMessage(containsString("[Output expression precision: 38 and scale: -2]"));
+    test(query);
+  }
+
+  @Test
+  public void testDecimalMultiplicationOverflowPrecision() throws Exception {
+    String query = "select cast('1' as decimal(9, 5)) * cast ('999999999999999999999999999.999999999' " +
+      "as decimal(38, 9)) as DEC38_1, cast('3' as decimal(9, 8)) * cast ('333333333.3333333333333333333' " +
+      "as decimal(38, 19)) as DEC38_2";
 
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
-        .baselineColumns("DEC38_1", "DEC38_2", "DEC38_3")
-        .baselineValues(new BigDecimal("1000000000000000000000000000.00000"), new BigDecimal("1.0000000000000000E+18"), new BigDecimal("1000000000.000000000000000000"))
+        .baselineColumns("DEC38_1", "DEC38_2")
+        .baselineValues(new BigDecimal("1000000000000000000000000000.00000"),
+          new BigDecimal("1000000000.000000000000000000"))
         .go();
   }
 
@@ -414,15 +443,16 @@ public void testDecimalRoundUp() throws Exception {
         "cast('999999999999999999.9999999999999999994' as decimal(38, 18)) as DEC38_2, " +
         "cast('999999999999999999.1234567895' as decimal(38, 9)) as DEC38_3, " +
         "cast('99999.12345' as decimal(18, 4)) as DEC18_1, " +
-        "cast('99999.99995' as decimal(18, 4)) as DEC18_2 " +
-        "from cp.`employee.json` where employee_id = 1";
+        "cast('99999.99995' as decimal(18, 4)) as DEC18_2";
 
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
         .baselineColumns("DEC38_1", "DEC38_2", "DEC38_3", "DEC18_1", "DEC18_2")
-        .baselineValues(new BigDecimal("1000000000000000000.000000000000000000"), new BigDecimal("999999999999999999.999999999999999999"),
-            new BigDecimal("999999999999999999.123456790"), new BigDecimal("99999.1235"), new BigDecimal("100000.0000"))
+        .baselineValues(new BigDecimal("1000000000000000000.000000000000000000"),
+          new BigDecimal("999999999999999999.999999999999999999"),
+          new BigDecimal("999999999999999999.123456790"), new BigDecimal("99999.1235"),
+          new BigDecimal("100000.0000"))
         .go();
   }
 
@@ -434,14 +464,15 @@ public void testDecimalDownwardCast() throws Exception {
         "cast((cast('99999999.6789' as decimal(38, 4))) as decimal(9, 0)) as DEC38_DEC19_1, " +
         "cast((cast('-999999999999999.6789' as decimal(38, 4))) as decimal(18, 2)) as DEC38_DEC18_1, " +
         "cast((cast('-999999999999999.6789' as decimal(38, 4))) as decimal(18, 0)) as DEC38_DEC18_2, " +
-        "cast((cast('100000000999999999.6789' as decimal(38, 4))) as decimal(28, 0)) as DEC38_DEC28_1 " +
-        "from cp.`employee.json` where employee_id = 1";
+        "cast((cast('100000000999999999.6789' as decimal(38, 4))) as decimal(28, 0)) as DEC38_DEC28_1";
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
-        .baselineColumns("DEC18_DEC9_1", "DEC18_DEC9_2", "DEC18_DEC9_3", "DEC38_DEC19_1", "DEC38_DEC18_1", "DEC38_DEC18_2", "DEC38_DEC28_1")
-        .baselineValues(new BigDecimal("12345.6789"), new BigDecimal("12345.68"), new BigDecimal("-12346"), new BigDecimal("100000000"),
-            new BigDecimal("-999999999999999.68"), new BigDecimal("-1000000000000000"), new BigDecimal("100000001000000000"))
+        .baselineColumns("DEC18_DEC9_1", "DEC18_DEC9_2", "DEC18_DEC9_3", "DEC38_DEC19_1", "DEC38_DEC18_1",
+          "DEC38_DEC18_2", "DEC38_DEC28_1")
+        .baselineValues(new BigDecimal("12345.6789"), new BigDecimal("12345.68"), new BigDecimal("-12346"),
+          new BigDecimal("100000000"), new BigDecimal("-999999999999999.68"),
+          new BigDecimal("-1000000000000000"), new BigDecimal("100000001000000000"))
         .go();
   }
 
@@ -458,15 +489,15 @@ public void testTruncateWithParamFunction() throws Exception {
             "trunc(cast('1234' as double), -4) as T_7,\n" +
             "trunc(cast('-1234' as double), -4) as T_8,\n" +
             "trunc(cast('8124674407369523212' as double), 0) as T_9,\n" +
-            "trunc(cast('81246744073695.395' as double), 1) as T_10\n" +
-        "FROM cp.`tpch/region.parquet` limit 1";
+            "trunc(cast('81246744073695.395' as double), 1) as T_10\n";
 
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
         .baselineColumns("T_1", "T_2", "T_3", "T_4", "T_5", "T_6", "T_7", "T_8", "T_9", "T_10")
-        .baselineValues(Double.valueOf("1234.45"), Double.valueOf("-1234.45"), Double.valueOf("1200.0"), Double.valueOf("-1200.0"), Double.valueOf("1234.0"),
-            Double.valueOf("-1234.0"), Double.valueOf("0.0"), Double.valueOf("0.0"), Double.valueOf("8.1246744073695232E18"), Double.valueOf("8.12467440736953E13"))
+        .baselineValues(Double.valueOf("1234.45"), Double.valueOf("-1234.45"), Double.valueOf("1200.0"),
+          Double.valueOf("-1200.0"), Double.valueOf("1234.0"), Double.valueOf("-1234.0"), Double.valueOf("0.0"),
+          Double.valueOf("0.0"), Double.valueOf("8.1246744073695232E18"), Double.valueOf("8.12467440736953E13"))
         .go();
   }
 
@@ -483,15 +514,14 @@ public void testRoundWithParamFunction() throws Exception {
             "round(cast('1234' as double), -4) as T_7,\n" +
             "round(cast('-1234' as double), -4) as T_8,\n" +
             "round(cast('8124674407369523212' as double), -4) as T_9,\n" +
-            "round(cast('81246744073695.395' as double), 1) as T_10\n" +
-        "FROM cp.`tpch/region.parquet` limit 1";
-
+            "round(cast('81246744073695.395' as double), 1) as T_10\n";
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
         .baselineColumns("T_1", "T_2", "T_3", "T_4", "T_5", "T_6", "T_7", "T_8", "T_9", "T_10")
-        .baselineValues(Double.valueOf("1234.46"), Double.valueOf("-1234.46"), Double.valueOf("1200.0"), Double.valueOf("-1200.0"), Double.valueOf("1234.0"),
-            Double.valueOf("-1234.0"), Double.valueOf("0.0"), Double.valueOf("0.0"), Double.valueOf("8.1246744073695201E18"), Double.valueOf("8.12467440736954E13"))
+        .baselineValues(Double.valueOf("1234.46"), Double.valueOf("-1234.46"), Double.valueOf("1200.0"),
+          Double.valueOf("-1200.0"), Double.valueOf("1234.0"), Double.valueOf("-1234.0"), Double.valueOf("0.0"),
+          Double.valueOf("0.0"), Double.valueOf("8.1246744073695201E18"), Double.valueOf("8.12467440736954E13"))
         .go();
 
   }
@@ -505,8 +535,8 @@ public void testRoundWithOneParam() throws Exception {
             "round(cast('23.45' as float)) round_float_1,\n" +
             "round(cast('23.55' as float)) round_float_2,\n" +
             "round(cast('8124674407369.2345' as double)) round_double_1,\n" +
-            "round(cast('8124674407369.589' as double)) round_double_2\n" +
-        "from cp.`tpch/region.parquet` limit 1";
+            "round(cast('8124674407369.589' as double)) round_double_2\n";
+
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
@@ -523,14 +553,14 @@ public void testToCharFunction() throws Exception {
         "to_char(cast('1234.5567' as decimal(9, 5)), '#,###.##') as DEC9_1, " +
         "to_char(cast('99999912399.9567' as decimal(18, 5)), '#.#####') DEC18_1, " +
         "to_char(cast('12345678912345678912.5567' as decimal(28, 5)), '#,###.#####') DEC28_1, " +
-        "to_char(cast('999999999999999999999999999.5' as decimal(38, 1)), '#.#') DEC38_1 " +
-        "FROM cp.`tpch/region.parquet` limit 1";
+        "to_char(cast('999999999999999999999999999.5' as decimal(38, 1)), '#.#') DEC38_1";
 
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
         .baselineColumns("FLOAT8_1", "FLOAT8_2", "DEC9_1", "DEC18_1", "DEC28_1", "DEC38_1")
-        .baselineValues("1,234.56", "$1,234.50", "1,234.56", "99999912399.9567", "12,345,678,912,345,678,912.5567", "999999999999999999999999999.5")
+        .baselineValues("1,234.56", "$1,234.50", "1,234.56", "99999912399.9567", "12,345,678,912,345,678,912.5567",
+          "999999999999999999999999999.5")
         .go();
   }
 
@@ -551,8 +581,7 @@ public void testConcatFunction() throws Exception {
   @Test
   public void testTimeStampConstant() throws Exception {
     String query = "SELECT " +
-        "timestamp '2008-2-23 12:23:23' as TS " +
-        "FROM cp.`tpch/region.parquet` limit 1";
+        "timestamp '2008-2-23 12:23:23' as TS";
 
     LocalDateTime date = LocalDateTime.parse("2008-02-23 12:23:23.0", formatTimeStamp);
     testBuilder()
@@ -568,8 +597,7 @@ public void testNullConstantsTimeTimeStampAndDate() throws Exception {
     String query = "SELECT " +
         "CAST(NULL AS TIME) AS t, " +
         "CAST(NULL AS TIMESTAMP) AS ts, " +
-        "CAST(NULL AS DATE) AS d " +
-        "FROM cp.`region.json` LIMIT 1";
+        "CAST(NULL AS DATE) AS d";
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
@@ -623,8 +651,8 @@ public void testDecimalAddIntConstant() throws Exception {
 
   @Test
   public void testSignFunction() throws Exception {
-    String query = "select sign(cast('1.23' as float)) as SIGN_FLOAT, sign(-1234.4567) as SIGN_DOUBLE, sign(23) as SIGN_INT " +
-        "from cp.`employee.json` where employee_id < 2";
+    String query = "select sign(cast('1.23' as float)) as SIGN_FLOAT, sign(-1234.4567) as SIGN_DOUBLE, " +
+      "sign(23) as SIGN_INT";
     testBuilder()
         .sqlQuery(query)
         .unOrdered()
@@ -636,9 +664,9 @@ public void testSignFunction() throws Exception {
 
   @Test
   public void testPadFunctions() throws Exception {
-    String query = "select rpad(first_name, 10) as RPAD_DEF, rpad(first_name, 10, '*') as RPAD_STAR, lpad(first_name, 10) as LPAD_DEF, lpad(first_name, 10, '*') as LPAD_STAR, " +
-        "lpad(first_name, 2) as LPAD_TRUNC, rpad(first_name, 2) as RPAD_TRUNC " +
-        "from cp.`employee.json` where employee_id = 1";
+    String query = "select rpad(first_name, 10) as RPAD_DEF, rpad(first_name, 10, '*') as RPAD_STAR, " +
+      "lpad(first_name, 10) as LPAD_DEF, lpad(first_name, 10, '*') as LPAD_STAR, lpad(first_name, 2) as LPAD_TRUNC, " +
+      "rpad(first_name, 2) as RPAD_TRUNC from cp.`employee.json` where employee_id = 1";
 
     testBuilder()
         .sqlQuery(query)
@@ -651,9 +679,9 @@ public void testPadFunctions() throws Exception {
 
   @Test
   public void testExtractSecond() throws Exception {
-    String query = "select extract(second from date '2008-2-23') as DATE_EXT, extract(second from timestamp '2008-2-23 10:00:20.123') as TS_EXT, " +
-        "extract(second from time '10:20:30.303') as TM_EXT " +
-        "from cp.`employee.json` where employee_id = 1";
+    String query = "select extract(second from date '2008-2-23') as DATE_EXT, " +
+      "extract(second from timestamp '2008-2-23 10:00:20.123') as TS_EXT, " +
+        "extract(second from time '10:20:30.303') as TM_EXT";
 
     testBuilder()
         .sqlQuery(query)
@@ -665,8 +693,7 @@ public void testExtractSecond() throws Exception {
 
   @Test
   public void testCastDecimalDouble() throws Exception {
-    String query = "select cast((cast('1.0001' as decimal(18, 9))) as double) DECIMAL_DOUBLE_CAST " +
-        "from cp.`employee.json` where employee_id = 1";
+    String query = "select cast((cast('1.0001' as decimal(18, 9))) as double) DECIMAL_DOUBLE_CAST";
 
     testBuilder()
         .sqlQuery(query)
@@ -678,8 +705,7 @@ public void testCastDecimalDouble() throws Exception {
 
   @Test
   public void testExtractSecondFromInterval() throws Exception {
-    String query = "select extract (second from interval '1 2:30:45.100' day to second) as EXT_INTDAY " +
-        "from cp.`employee.json` where employee_id = 1";
+    String query = "select extract (second from interval '1 2:30:45.100' day to second) as EXT_INTDAY";
 
     testBuilder()
         .sqlQuery(query)
@@ -693,8 +719,7 @@ public void testExtractSecondFromInterval() throws Exception {
   public void testFunctionCaseInsensitiveNames() throws Exception {
     String query = "SELECT to_date('2003/07/09', 'yyyy/MM/dd') as col1, " +
         "TO_DATE('2003/07/09', 'yyyy/MM/dd') as col2, " +
-        "To_DaTe('2003/07/09', 'yyyy/MM/dd') as col3 " +
-        "from cp.`employee.json` LIMIT 1";
+        "To_DaTe('2003/07/09', 'yyyy/MM/dd') as col3";
 
     LocalDate date = LocalDate.parse("2003-07-09");
 
@@ -708,8 +733,8 @@ public void testFunctionCaseInsensitiveNames() throws Exception {
 
   @Test
   public void testDecimal18Decimal38Comparison() throws Exception {
-    String query = "select cast('-999999999.999999999' as decimal(18, 9)) = cast('-999999999.999999999' as decimal(38, 18)) as CMP " +
-        "from cp.`employee.json` where employee_id = 1";
+    String query = "select cast('-999999999.999999999' as decimal(18, 9)) = cast('-999999999.999999999' as " +
+      "decimal(38, 18)) as CMP";
 
     testBuilder()
         .sqlQuery(query)
@@ -721,8 +746,7 @@ public void testDecimal18Decimal38Comparison() throws Exception {
 
   @Test
   public void testOptiqDecimalCapping() throws Exception {
-    String query = "select  cast('12345.678900000' as decimal(18, 9))=cast('12345.678900000' as decimal(38, 9)) as CMP " +
-        "from cp.`employee.json` where employee_id = 1";
+    String query = "select  cast('12345.678900000' as decimal(18, 9))=cast('12345.678900000' as decimal(38, 9)) as CMP";
 
     testBuilder()
         .sqlQuery(query)
@@ -734,8 +758,7 @@ public void testOptiqDecimalCapping() throws Exception {
 
   @Test
   public void testNegative() throws Exception {
-    String query = "select  negative(cast(2 as bigint)) as NEG\n" +
-        "from cp.`employee.json` where employee_id = 1";
+    String query = "select  negative(cast(2 as bigint)) as NEG\n";
 
     testBuilder()
         .sqlQuery(query)
@@ -760,8 +783,8 @@ public void testOptiqValidationFunctions() throws Exception {
 
   @Test
   public void testToTimeStamp() throws Exception {
-    String query = "select to_timestamp(cast('800120400.12312' as decimal(38, 5))) as DEC38_TS, to_timestamp(200120400) as INT_TS\n" +
-        "from cp.`employee.json` where employee_id < 2";
+    String query = "select to_timestamp(cast('800120400.12312' as decimal(38, 5))) as DEC38_TS, " +
+      "to_timestamp(200120400) as INT_TS\n";
 
     LocalDateTime result1 = Instant.ofEpochMilli(800120400123L).atZone(ZoneOffset.systemDefault()).toLocalDateTime();
     LocalDateTime result2 = Instant.ofEpochMilli(200120400000L).atZone(ZoneOffset.systemDefault()).toLocalDateTime();
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestVarDecimalFunctions.java b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestVarDecimalFunctions.java
index 4087e675931..d4072a9cfe3 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestVarDecimalFunctions.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestVarDecimalFunctions.java
@@ -18,17 +18,22 @@
 package org.apache.drill.exec.fn.impl;
 
 import org.apache.drill.categories.SqlFunctionTest;
+import org.apache.drill.common.exceptions.UserRemoteException;
 import org.apache.drill.exec.planner.physical.PlannerSettings;
 import org.apache.drill.test.BaseTestQuery;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
+import org.junit.rules.ExpectedException;
 
 import java.math.BigDecimal;
 import java.math.MathContext;
 import java.math.RoundingMode;
 
+import static org.hamcrest.CoreMatchers.containsString;
+
 @Category(SqlFunctionTest.class)
 public class TestVarDecimalFunctions extends BaseTestQuery {
 
@@ -42,6 +47,9 @@ public static void disableDecimalDataType() {
     resetSessionOption(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
   }
 
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
   // Tests for math functions
 
   @Test
@@ -59,9 +67,9 @@ public void testDecimalAdd() throws Exception {
             "cast('15.02' as DECIMAL(4, 2)) - cast('12.93' as DECIMAL(4, 2)) as s4,\n" +
             "cast('11.02' as DECIMAL(4, 2)) - cast('12.93' as DECIMAL(4, 2)) as s5,\n" +
             "cast('0' as DECIMAL(36, 2)) - cast('12.93' as DECIMAL(36, 2)) as s6,\n" +
-            // check trimming (negative scale)
-            "cast('99999999999999999999999999992345678912' as DECIMAL(38, 0))\n" +
-            "+ cast('32345678912345678912345678912345678912' as DECIMAL(38, 0)) as s7";
+            // check trimming (digits after decimal point will be trimmed from result)
+            "cast('9999999999999999999999999999234567891.1' as DECIMAL(38, 1))\n" +
+            "+ cast('3234567891234567891234567891234567891.1' as DECIMAL(38, 1)) as s7";
     testBuilder()
         .sqlQuery(query)
         .ordered()
@@ -73,10 +81,23 @@ public void testDecimalAdd() throws Exception {
             new BigDecimal("1358024680358024680358024680358024.679"),
             new BigDecimal("1234567891234567891234567891234567.890"),
             new BigDecimal("2.09"), new BigDecimal("-1.91"), new BigDecimal("-12.93"),
-            new BigDecimal("1.3234567891234567891234567890469135782E+38"))
+            new BigDecimal("13234567891234567891234567890469135782"))
         .go();
   }
 
+  @Test
+  public void testDecimalAdd_OverflowWithNegativeScale() throws Exception {
+    String query =
+      "select\n" +
+        // check trimming (negative scale)
+        "cast('99999999999999999999999999992345678912' as DECIMAL(38, 0))\n" +
+        "+ cast('32345678912345678912345678912345678912' as DECIMAL(38, 0)) as s7";
+    expectedException.expect(UserRemoteException.class);
+    expectedException.expectMessage(containsString("SYSTEM ERROR"));
+    expectedException.expectMessage(containsString("[Output expression precision: 38 and scale: -1]"));
+    test(query);
+  }
+
   @Test
   public void testDecimalMultiply() throws Exception {
     String query =


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services