You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@drill.apache.org by ja...@apache.org on 2014/04/23 05:14:41 UTC

[03/10] DRILL-332: Support for decimal data type

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/codegen/templates/FixedValueVectors.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/FixedValueVectors.java b/exec/java-exec/src/main/codegen/templates/FixedValueVectors.java
index caabade..cba9f97 100644
--- a/exec/java-exec/src/main/codegen/templates/FixedValueVectors.java
+++ b/exec/java-exec/src/main/codegen/templates/FixedValueVectors.java
@@ -20,6 +20,8 @@ import java.lang.Long;
 import java.lang.Override;
 import java.sql.Time;
 import java.sql.Timestamp;
+import java.math.BigDecimal;
+import java.math.BigInteger;
 
 <@pp.dropOutputFile />
 <#list vv.types as type>
@@ -44,9 +46,7 @@ package org.apache.drill.exec.vector;
  */
 @SuppressWarnings("unused")
 public final class ${minor.class}Vector extends BaseDataValueVector implements FixedWidthVector{
-  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(${minor.class}Vector.class);
 
- 
   private final Accessor accessor = new Accessor();
   private final Mutator mutator = new Mutator();
   
@@ -176,8 +176,10 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
     <#if (type.width > 8)>
 
     public ${minor.javaType!type.javaType} get(int index) {
-      ByteBuf dst = allocator.buffer(${type.width});
+      ByteBuf dst = io.netty.buffer.Unpooled.wrappedBuffer(new byte[${type.width}]);
+      //dst = new io.netty.buffer.SwappedByteBuf(dst);
       data.getBytes(index * ${type.width}, dst, 0, ${type.width});
+
       return dst;
     }
 
@@ -290,8 +292,63 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
               append(millis));
     }
 
-    <#else>
+    <#elseif (minor.class == "Decimal28Sparse") || (minor.class == "Decimal38Sparse") || (minor.class == "Decimal28Dense") || (minor.class == "Decimal38Dense")>
+
+    public void get(int index, ${minor.class}Holder holder) {
+
+        holder.start = index * ${type.width};
+
+        holder.buffer = data;
+
+        /* The buffer within the value vector is little endian.
+         * For the dense representation though, we use big endian
+         * byte ordering (internally). This is because we shift bits to the right and
+         * big endian ordering makes sense for this purpose.  So we have to deal with
+         * the sign bit for the two representation in a slightly different fashion
+         */
+
+        // Get the sign of the decimal
+          <#if minor.class.endsWith("Sparse")>
+          if ((holder.buffer.getInt(holder.start) & 0x80000000) != 0) {
+          <#elseif minor.class.endsWith("Dense")>
+          if ((holder.buffer.getInt(holder.start) & 0x00000080) != 0) {
+          </#if>
+            holder.sign = true;
+        }
+
+        holder.scale = getField().getScale();
+        holder.precision = getField().getPrecision();
+
+
+    }
+
+    void get(int index, Nullable${minor.class}Holder holder) {
 
+        holder.start = index * ${type.width};
+
+        holder.buffer = data;
+
+          // Get the sign the of the decimal
+          <#if minor.class.endsWith("Sparse")>
+          if ((holder.buffer.getInt(holder.start) & 0x80000000) != 0) {
+          <#elseif minor.class.endsWith("Dense")>
+          if ((holder.buffer.getInt(holder.start) & 0x00000080) != 0) {
+          </#if>
+            holder.sign = true;
+        }
+    }
+
+      @Override
+      public Object getObject(int index) {
+      <#if (minor.class == "Decimal28Sparse") || (minor.class == "Decimal38Sparse")>
+      // Get the BigDecimal object
+      return org.apache.drill.common.util.DecimalUtility.getBigDecimalFromSparse(data, index * ${type.width}, ${minor.nDecimalDigits}, getField().getScale());
+      <#else>
+      return org.apache.drill.common.util.DecimalUtility.getBigDecimalFromDense(data, index * ${type.width}, ${minor.nDecimalDigits}, getField().getScale(), ${minor.maxPrecisionDigits}, ${type.width});
+      </#if>
+    }
+
+    <#else>
     public void get(int index, ${minor.class}Holder holder){
       holder.buffer = data;
       holder.start = index * ${type.width};
@@ -304,13 +361,18 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
 
     @Override
     public Object getObject(int index) {
-      ByteBuf dst = allocator.buffer(${type.width});
-      data.getBytes(index, dst, 0, ${type.width});
+
+      ByteBuf dst = io.netty.buffer.Unpooled.wrappedBuffer(new byte[${type.width}]);
+      //dst = new io.netty.buffer.SwappedByteBuf(dst);
+      data.getBytes(index * ${type.width}, dst, 0, ${type.width});
+
       return dst;
+
+
+
     }
 
     </#if>
-
     <#else> <#-- type.width <= 8 -->
 
     public ${minor.javaType!type.javaType} get(int index) {
@@ -358,17 +420,32 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
         return new Time(time.getMillis());
     }
 
+
+
+    <#elseif minor.class == "Decimal9" || minor.class == "Decimal18">
+    @Override
+    public Object getObject(int index) {
+
+        BigInteger value = BigInteger.valueOf(((${type.boxedType})get(index)).${type.javaType}Value());
+        return new BigDecimal(value, getField().getScale());
+    }
+
     <#else>
     public Object getObject(int index) {
       return get(index);
     }
     </#if>
-    
     public void get(int index, ${minor.class}Holder holder){
+      <#if minor.class.startsWith("Decimal")>
+      holder.scale = getField().getScale();
+      holder.precision = getField().getPrecision();
+      </#if>
+
       holder.value = data.get${(minor.javaType!type.javaType)?cap_first}(index * ${type.width});
     }
 
     void get(int index, Nullable${minor.class}Holder holder){
+
       holder.value = data.get${(minor.javaType!type.javaType)?cap_first}(index * ${type.width});
     }
 
@@ -397,7 +474,7 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
     */
   <#if (type.width > 8)>
    public void set(int index, <#if (type.width > 4)>${minor.javaType!type.javaType}<#else>int</#if> value) {
-     data.setBytes(index * ${type.width}, value);
+     data.setBytes(index * ${type.width}, value, 0, ${type.width});
    }
 
    <#if (minor.class == "TimeStampTZ")>
@@ -473,6 +550,50 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
      set(index, holder);
      return true;
    }
+
+   <#elseif (minor.class == "Decimal28Sparse" || minor.class == "Decimal38Sparse") || (minor.class == "Decimal28Dense") || (minor.class == "Decimal38Dense")>
+
+   public void set(int index, ${minor.class}Holder holder){
+      data.setBytes(index * ${type.width}, holder.buffer, holder.start, ${type.width});
+
+      // Set the sign of the decimal
+      if (holder.sign == true) {
+          int value = data.getInt(index * ${type.width});
+          <#if minor.class.endsWith("Sparse")>
+          data.setInt(index * ${type.width}, (value | 0x80000000));
+          <#elseif minor.class.endsWith("Dense")>
+          data.setInt(index * ${type.width}, (value | 0x00000080));
+          </#if>
+
+      }
+   }
+
+   void set(int index, Nullable${minor.class}Holder holder){
+       data.setBytes(index * ${type.width}, holder.buffer, holder.start, ${type.width});
+
+      // Set the sign of the decimal
+      if (holder.sign == true) {
+          int value = data.getInt(index * ${type.width});
+          <#if minor.class.endsWith("Sparse")>
+          data.setInt(index * ${type.width}, (value | 0x80000000));
+          <#elseif minor.class.endsWith("Dense")>
+          data.setInt(index * ${type.width}, (value | 0x00000080));
+          </#if>
+      }
+   }
+
+   public boolean setSafe(int index,  Nullable${minor.class}Holder holder){
+       if(index >= getValueCapacity()) return false;
+       set(index, holder);
+       return true;
+   }
+
+   public boolean setSafe(int index,  ${minor.class}Holder holder){
+       if(index >= getValueCapacity()) return false;
+       set(index, holder);
+       return true;
+   }
+
    <#else>
    public void set(int index, ${minor.class}Holder holder){
      data.setBytes(index * ${type.width}, holder.buffer, holder.start, ${type.width});
@@ -500,8 +621,8 @@ public final class ${minor.class}Vector extends BaseDataValueVector implements F
        }
      }
    }
-   
-  <#else> <#-- type.width <= 8 -->
+
+   <#else> <#-- type.width <= 8 -->
    public void set(int index, <#if (type.width >= 4)>${minor.javaType!type.javaType}<#else>int</#if> value) {
      data.set${(minor.javaType!type.javaType)?cap_first}(index * ${type.width}, value);
    }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/codegen/templates/NullableValueVectors.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/NullableValueVectors.java b/exec/java-exec/src/main/codegen/templates/NullableValueVectors.java
index b23e53d..bb692dc 100644
--- a/exec/java-exec/src/main/codegen/templates/NullableValueVectors.java
+++ b/exec/java-exec/src/main/codegen/templates/NullableValueVectors.java
@@ -266,11 +266,30 @@ public final class ${className} extends BaseValueVector implements <#if type.maj
     public void get(int index, Nullable${minor.class}Holder holder){
       holder.isSet = bits.getAccessor().get(index);
       values.getAccessor().get(index, holder);
+
+      <#if minor.class.startsWith("Decimal")>
+      holder.scale = getField().getScale();
+      holder.precision = getField().getPrecision();
+      </#if>
     }
 
     @Override
     public Object getObject(int index) {
-      return isNull(index) ? null : values.getAccessor().getObject(index);
+
+      if (isNull(index)) {
+          return null;
+      }
+      <#if minor.class == "Decimal9" || minor.class == "Decimal18">
+      // Get the value and construct a BigDecimal Object
+      BigInteger value = BigInteger.valueOf(((${type.boxedType})values.getAccessor().get(index)).${type.javaType}Value());
+      return new BigDecimal(value, getField().getScale());
+      <#elseif minor.class == "Decimal38Sparse" || minor.class == "Decimal28Sparse">
+      return org.apache.drill.common.util.DecimalUtility.getBigDecimalFromSparse(values.getData(), index * ${type.width}, ${minor.nDecimalDigits}, getField().getScale());
+      <#elseif minor.class == "Decimal38Dense" || minor.class == "Decimal28Dense">
+      return org.apache.drill.common.util.DecimalUtility.getBigDecimalFromDense(values.getData(), index * ${type.width}, ${minor.nDecimalDigits}, getField().getScale(), ${minor.maxPrecisionDigits}, ${type.width});
+      <#else>
+      return values.getAccessor().getObject(index);
+      </#if>
     }
 
     public int getValueCount(){
@@ -362,8 +381,15 @@ public final class ${className} extends BaseValueVector implements <#if type.maj
       values.getMutator().set(index, holder);
       <#if type.major == "VarLen">lastSet = index;</#if>
     }
-    
-    public boolean setSafe(int index, <#if type.major == "VarLen" || minor.class == "TimeStampTZ" || minor.class == "Interval" || minor.class == "IntervalDay">Nullable${minor.class}Holder <#elseif (type.width < 4)>int<#else>${minor.javaType!type.javaType}</#if> value){
+
+    //public boolean setSafe(int index, <#if type.major == "VarLen" || minor.class == "TimeStampTZ" || minor.class == "Interval" || minor.class == "IntervalDay">Nullable${minor.class}Holder <#elseif (type.width < 4)>int<#else>${minor.javaType!type.javaType}</#if> value){
+
+    <#if type.major == "VarLen" || minor.class == "Decimal28Sparse" || minor.class == "Decimal38Sparse" || minor.class == "Decimal28Dense" || minor.class == "Decimal38Dense" || minor.class == "TimeStampTZ" || minor.class == "Interval" || minor.class == "IntervalDay">
+    public boolean setSafe(int index, Nullable${minor.class}Holder value) {
+    <#else>
+    public boolean setSafe(int index, ${minor.javaType!type.javaType} value) {
+    </#if>
+
       <#if type.major == "VarLen">
       for (int i = lastSet + 1; i < index; i++) {
         values.getMutator().set(i, new byte[]{});

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/SqlAccessors.java b/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
index cd6955e..0e6b4a7 100644
--- a/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
+++ b/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
@@ -107,6 +107,11 @@ public class ${name}Accessor extends AbstractSqlAccessor{
   public byte[] getBytes(int index) {
       return null;
   }
+  <#elseif minor.class.startsWith("Decimal")>
+  @Override
+  public BigDecimal getBigDecimal(int index) {
+      return (BigDecimal) ac.getObject(index);
+  }
   <#else>
   @Override
   public ${javaType} get${javaType?cap_first}(int index){

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/codegen/templates/TypeHelper.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/TypeHelper.java b/exec/java-exec/src/main/codegen/templates/TypeHelper.java
index 0ceb14c..bd89ce7 100644
--- a/exec/java-exec/src/main/codegen/templates/TypeHelper.java
+++ b/exec/java-exec/src/main/codegen/templates/TypeHelper.java
@@ -139,8 +139,9 @@ public class TypeHelper {
 <#list vv.types as type>
   <#list type.minor as minor>
     case ${minor.class?upper_case} :
-      <#if minor.class?starts_with("Var") || minor.class == "TimeStampTZ" || minor.class == "IntervalDay" || minor.class == "Interval">
-         throw new UnsupportedOperationException(type.getMinorType() + " type is not supported."); 
+      <#if minor.class?starts_with("Var") || minor.class == "TimeStampTZ" || minor.class == "IntervalDay" || minor.class == "Interval" ||
+        minor.class?starts_with("Decimal28") ||  minor.class?starts_with("Decimal38")>
+         throw new UnsupportedOperationException(type.getMinorType() + " type is not supported.");
       <#else>
       holder = new ${minor.class}Holder(); 
       ((${minor.class}Holder)holder).value = ((${minor.class}Vector) vector).getAccessor().get(index);

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/codegen/templates/ValueHolders.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/ValueHolders.java b/exec/java-exec/src/main/codegen/templates/ValueHolders.java
index f63077e..e36e655 100644
--- a/exec/java-exec/src/main/codegen/templates/ValueHolders.java
+++ b/exec/java-exec/src/main/codegen/templates/ValueHolders.java
@@ -42,8 +42,7 @@ public final class ${className} implements ValueHolder{
       </#if>
       
       <#if type.major != "VarLen">
-      
-      <#if (type.width > 8)>
+
       <#if (minor.class == "TimeStampTZ")>
       public long value;
       public int index;
@@ -54,19 +53,77 @@ public final class ${className} implements ValueHolder{
       <#elseif (minor.class == "IntervalDay")>
       public int days;
       public int milliSeconds;
-      <#else>
+    <#elseif minor.class.startsWith("Decimal")>
+    public int scale;
+    public int precision;
+    public static final int maxPrecision = ${minor.maxPrecisionDigits};
+    <#if minor.class.startsWith("Decimal28") || minor.class.startsWith("Decimal38")>
+    public boolean sign;
+    public int start;
+    public ByteBuf buffer;
+    public static final int nDecimalDigits = ${minor.nDecimalDigits};
+
+
+    public int getInteger(int index) {
+        int value = buffer.getInt(start + (index * 4));
+
+        if (index == 0) {
+            /* the first byte contains sign bit, return value without it */
+            <#if minor.class.endsWith("Sparse")>
+            value = (value & 0x7FFFFFFF);
+            <#elseif minor.class.endsWith("Dense")>
+            value = (value & 0x0000007F);
+            </#if>
+        }
+        return value;
+    }
+
+    public void setInteger(int index, int value) {
+        buffer.setInt(start + (index * 4), value);
+    }
+
+    // TODO: This is a temporary hack to swap holders. We need a generic solution for this issue
+    public void swap(${className} right) {
+        int tempScale = this.scale;
+        int tempPrec = this.precision;
+        boolean tempSign = this.sign;
+        ByteBuf tempBuf = this.buffer;
+        int start = this.start;
+
+        this.scale = right.scale;
+        this.precision = right.precision;
+        this.sign = right.sign;
+        this.buffer = right.buffer;
+        this.start = right.start;
+
+        right.scale = tempScale;
+        right.precision = tempPrec;
+        right.sign = tempSign;
+        right.buffer = tempBuf;
+        right.start = start;
+
+        <#if mode.prefix == "Nullable">
+        int isSet = this.isSet;
+        this.isSet = right.isSet;
+        right.isSet = isSet;
+        </#if>
+    }
+
+    <#else>
+    public ${minor.javaType!type.javaType} value;
+    </#if>
+
+      <#elseif (type.width > 8)>
       public int start;
       public ByteBuf buffer;
-      </#if>
       <#else>
         public ${minor.javaType!type.javaType} value;
-      
       </#if>
       <#else>
       /** The first offset (inclusive) into the buffer. **/
       public int start;
       
-      /** The last offset (exclusive) into the buffer. **/
+  /** The last offset (exclusive) into the buffer. **/
       public int end;
       
       /** The buffer holding actual values. **/
@@ -95,8 +152,6 @@ public final class ${className} implements ValueHolder{
       /** The Vector holding the actual values. **/
       public ${minor.class}Vector vector;
     </#if>
-  
-    
 }
 
 </#list>

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
index 2a87bab..2b125cd 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/compile/sig/ConstantExpressionIdentifier.java
@@ -37,6 +37,10 @@ import org.apache.drill.common.expression.ValueExpressions.IntervalYearExpressio
 import org.apache.drill.common.expression.ValueExpressions.IntervalDayExpression;
 import org.apache.drill.common.expression.ValueExpressions.TimeStampExpression;
 import org.apache.drill.common.expression.ValueExpressions.TimeExpression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal9Expression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal18Expression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal28Expression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal38Expression;
 import org.apache.drill.common.expression.ValueExpressions.QuotedString;
 import org.apache.drill.common.expression.visitors.ExprVisitor;
 
@@ -134,16 +138,31 @@ public class ConstantExpressionIdentifier implements ExprVisitor<Boolean, Identi
   }
 
   @Override
+  public Boolean visitDecimal9Constant(Decimal9Expression decExpr, IdentityHashMap<LogicalExpression, Object> value){
+    return true;
+  }
+
+  @Override
   public Boolean visitTimeConstant(TimeExpression intExpr, IdentityHashMap<LogicalExpression, Object> value){
     return true;
   }
 
   @Override
+  public Boolean visitDecimal18Constant(Decimal18Expression decExpr, IdentityHashMap<LogicalExpression, Object> value){
+    return true;
+  }
+
+  @Override
   public Boolean visitIntervalYearConstant(IntervalYearExpression intExpr, IdentityHashMap<LogicalExpression, Object> value){
     return true;
   }
 
   @Override
+  public Boolean visitDecimal28Constant(Decimal28Expression decExpr, IdentityHashMap<LogicalExpression, Object> value){
+    return true;
+  }
+
+  @Override
   public Boolean visitIntervalDayConstant(IntervalDayExpression intExpr, IdentityHashMap<LogicalExpression, Object> value){
     return true;
   }
@@ -154,6 +173,11 @@ public class ConstantExpressionIdentifier implements ExprVisitor<Boolean, Identi
   }
 
   @Override
+  public Boolean visitDecimal38Constant(Decimal38Expression decExpr, IdentityHashMap<LogicalExpression, Object> value){
+    return true;
+  }
+
+  @Override
   public Boolean visitDoubleConstant(DoubleExpression dExpr, IdentityHashMap<LogicalExpression, Object> value){
     return true;
   }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
index aff47db..2e632a3 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/EvaluationVisitor.java
@@ -20,6 +20,7 @@ package org.apache.drill.exec.expr;
 import java.util.List;
 import java.util.Set;
 
+import io.netty.buffer.ByteBuf;
 import org.apache.drill.common.expression.CastExpression;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.FunctionHolderExpression;
@@ -38,6 +39,10 @@ import org.apache.drill.common.expression.ValueExpressions.IntervalYearExpressio
 import org.apache.drill.common.expression.ValueExpressions.IntervalDayExpression;
 import org.apache.drill.common.expression.ValueExpressions.TimeStampExpression;
 import org.apache.drill.common.expression.ValueExpressions.TimeExpression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal9Expression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal18Expression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal28Expression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal38Expression;
 import org.apache.drill.common.expression.ValueExpressions.QuotedString;
 import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
 import org.apache.drill.common.types.TypeProtos.MajorType;
@@ -76,7 +81,6 @@ public class EvaluationVisitor {
     Set<LogicalExpression> constantBoundaries = ConstantExpressionIdentifier.getConstantExpressionSet(e);
     //Set<LogicalExpression> constantBoundaries = Collections.emptySet();
     return e.accept(new ConstantFilter(constantBoundaries), generator);
-    
   }
 
   private class EvalVisitor extends AbstractExprVisitor<HoldingContainer, ClassGenerator<?>, RuntimeException> {
@@ -370,23 +374,72 @@ public class EvaluationVisitor {
       JVar var = generator.declareClassField("intervalday", holderType);
       JExpression dayLiteral = JExpr.lit(e.getIntervalDay());
       JExpression millisLiteral = JExpr.lit(e.getIntervalMillis());
-
       setup.assign(var, ((JClass)generator.getModel().ref(ValueHolderHelper.class)).staticInvoke("getIntervalDayHolder").arg(dayLiteral).arg(millisLiteral));
       return new HoldingContainer(majorType, var, null, null);
     }
 
     @Override
+    public HoldingContainer visitDecimal9Constant(Decimal9Expression e, ClassGenerator<?> generator) throws RuntimeException {
+      MajorType majorType = e.getMajorType();
+      JBlock setup = generator.getBlock(BlockType.SETUP);
+      JType holderType = generator.getHolderType(majorType);
+      JVar var = generator.declareClassField("dec9", holderType);
+      JExpression valueLiteral = JExpr.lit(e.getIntFromDecimal());
+      JExpression scaleLiteral = JExpr.lit(e.getScale());
+      JExpression precisionLiteral = JExpr.lit(e.getPrecision());
+      setup.assign(var, ((JClass)generator.getModel().ref(ValueHolderHelper.class)).staticInvoke("getDecimal9Holder").arg(valueLiteral).arg(scaleLiteral).arg(precisionLiteral));
+      return new HoldingContainer(majorType, var, null, null);
+    }
+
+    @Override
+    public HoldingContainer visitDecimal18Constant(Decimal18Expression e, ClassGenerator<?> generator) throws RuntimeException {
+      MajorType majorType = e.getMajorType();
+      JBlock setup = generator.getBlock(BlockType.SETUP);
+      JType holderType = generator.getHolderType(majorType);
+      JVar var = generator.declareClassField("dec18", holderType);
+      JExpression valueLiteral = JExpr.lit(e.getLongFromDecimal());
+      JExpression scaleLiteral = JExpr.lit(e.getScale());
+      JExpression precisionLiteral = JExpr.lit(e.getPrecision());
+      setup.assign(var, ((JClass)generator.getModel().ref(ValueHolderHelper.class)).staticInvoke("getDecimal18Holder").arg(valueLiteral).arg(scaleLiteral).arg(precisionLiteral));
+      return new HoldingContainer(majorType, var, null, null);
+    }
+
+    @Override
+    public HoldingContainer visitDecimal28Constant(Decimal28Expression e, ClassGenerator<?> generator)
+        throws RuntimeException {
+      MajorType majorType = e.getMajorType();
+      JBlock setup = generator.getBlock(BlockType.SETUP);
+      JType holderType = generator.getHolderType(majorType);
+      JVar var = generator.declareClassField("dec28", holderType);
+      JExpression stringLiteral = JExpr.lit(e.getBigDecimal().toString());
+      setup.assign(var, ((JClass)generator.getModel().ref(ValueHolderHelper.class)).staticInvoke("getDecimal28Holder").arg(stringLiteral));
+      return new HoldingContainer(majorType, var, null, null);
+    }
+
+    @Override
+    public HoldingContainer visitDecimal38Constant(Decimal38Expression e, ClassGenerator<?> generator)
+        throws RuntimeException {
+      MajorType majorType = e.getMajorType();
+      JBlock setup = generator.getBlock(BlockType.SETUP);
+      JType holderType = generator.getHolderType(majorType);
+      JVar var = generator.declareClassField("dec38", holderType);
+      JExpression stringLiteral = JExpr.lit(e.getBigDecimal().toString());
+      setup.assign(var, ((JClass)generator.getModel().ref(ValueHolderHelper.class)).staticInvoke("getVarCharHolder").arg(stringLiteral));
+      return new HoldingContainer(majorType, var, null, null);
+    }
+
+    @Override
     public HoldingContainer visitCastExpression(CastExpression e, ClassGenerator<?> value) throws RuntimeException {
       throw new UnsupportedOperationException("CastExpression is not expected here. "+
         "It should have been converted to FunctionHolderExpression in materialization");
     }
-  }
 
+  }
   private class ConstantFilter extends EvalVisitor {
 
     private Set<LogicalExpression> constantBoundaries;
-    
-    
+
+
     public ConstantFilter(Set<LogicalExpression> constantBoundaries) {
       super();
       this.constantBoundaries = constantBoundaries;
@@ -420,7 +473,7 @@ public class EvaluationVisitor {
         HoldingContainer c = super.visitIfExpression(e, generator);
         // generator.getMappingSet().exitConstant();
         // return c;
-        return renderConstantExpression(generator, c); 
+        return renderConstantExpression(generator, c);
       } else if (generator.getMappingSet().isWithinConstant()) {
         return super.visitIfExpression(e, generator).setConstant(true);
       } else {
@@ -458,6 +511,59 @@ public class EvaluationVisitor {
       }
     }
 
+
+    @Override
+    public HoldingContainer visitDecimal9Constant(Decimal9Expression e, ClassGenerator<?> generator) throws RuntimeException {
+      if (constantBoundaries.contains(e)) {
+        generator.getMappingSet().enterConstant();
+        HoldingContainer c = super.visitDecimal9Constant(e, generator);
+        return renderConstantExpression(generator, c);
+      } else if (generator.getMappingSet().isWithinConstant()) {
+        return super.visitDecimal9Constant(e, generator).setConstant(true);
+      } else {
+        return super.visitDecimal9Constant(e, generator);
+      }
+    }
+
+    @Override
+    public HoldingContainer visitDecimal18Constant(Decimal18Expression e, ClassGenerator<?> generator) throws RuntimeException {
+      if (constantBoundaries.contains(e)) {
+        generator.getMappingSet().enterConstant();
+        HoldingContainer c = super.visitDecimal18Constant(e, generator);
+        return renderConstantExpression(generator, c);
+      } else if (generator.getMappingSet().isWithinConstant()) {
+        return super.visitDecimal18Constant(e, generator).setConstant(true);
+      } else {
+        return super.visitDecimal18Constant(e, generator);
+      }
+    }
+
+    @Override
+    public HoldingContainer visitDecimal28Constant(Decimal28Expression e, ClassGenerator<?> generator) throws RuntimeException {
+      if (constantBoundaries.contains(e)) {
+        generator.getMappingSet().enterConstant();
+        HoldingContainer c = super.visitDecimal28Constant(e, generator);
+        return renderConstantExpression(generator, c);
+      } else if (generator.getMappingSet().isWithinConstant()) {
+        return super.visitDecimal28Constant(e, generator).setConstant(true);
+      } else {
+        return super.visitDecimal28Constant(e, generator);
+      }
+    }
+
+    @Override
+    public HoldingContainer visitDecimal38Constant(Decimal38Expression e, ClassGenerator<?> generator) throws RuntimeException {
+      if (constantBoundaries.contains(e)) {
+        generator.getMappingSet().enterConstant();
+        HoldingContainer c = super.visitDecimal38Constant(e, generator);
+        return renderConstantExpression(generator, c);
+      } else if (generator.getMappingSet().isWithinConstant()) {
+        return super.visitDecimal38Constant(e, generator).setConstant(true);
+      } else {
+        return super.visitDecimal38Constant(e, generator);
+      }
+    }
+
     @Override
     public HoldingContainer visitIntConstant(IntExpression e, ClassGenerator<?> generator) throws RuntimeException {
       if (constantBoundaries.contains(e)) {
@@ -561,7 +667,7 @@ public class EvaluationVisitor {
       }
     }
 
-    
+
     @Override
     public HoldingContainer visitUnknown(LogicalExpression e, ClassGenerator<?> generator) throws RuntimeException {
       if (constantBoundaries.contains(e)) {
@@ -573,7 +679,7 @@ public class EvaluationVisitor {
       } else if (generator.getMappingSet().isWithinConstant()) {
         return super.visitUnknown(e, generator).setConstant(true);
       } else {
-        return super.visitUnknown(e, generator); 
+        return super.visitUnknown(e, generator);
       }
     }
 
@@ -589,7 +695,7 @@ public class EvaluationVisitor {
       } else if (generator.getMappingSet().isWithinConstant()) {
         return super.visitQuotedStringConstant(e, generator).setConstant(true);
       } else {
-        return super.visitQuotedStringConstant(e, generator);          
+        return super.visitQuotedStringConstant(e, generator);
       }
     }
 
@@ -610,14 +716,13 @@ public class EvaluationVisitor {
     }
 
     /* Get a HoldingContainer for a constant expression. The returned HoldingContainder will indicate it's for
-     * a constant expression. 
-     * */    
+     * a constant expression.
+     * */
     private HoldingContainer renderConstantExpression(ClassGenerator<?> generator, HoldingContainer input){
       JVar fieldValue = generator.declareClassField("constant", generator.getHolderType(input.getMajorType()));
       generator.getEvalBlock().assign(fieldValue, input.getHolder());
       generator.getMappingSet().exitConstant();
-      return new HoldingContainer(input.getMajorType(), fieldValue, fieldValue.ref("value"), fieldValue.ref("isSet")).setConstant(true);                        
+      return new HoldingContainer(input.getMajorType(), fieldValue, fieldValue.ref("value"), fieldValue.ref("isSet")).setConstant(true);
     }
-
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
----------------------------------------------------------------------
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 1d8070c..f9572db 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
@@ -38,6 +38,10 @@ import org.apache.drill.common.expression.ValueExpressions.IntervalYearExpressio
 import org.apache.drill.common.expression.ValueExpressions.IntervalDayExpression;
 import org.apache.drill.common.expression.ValueExpressions.TimeStampExpression;
 import org.apache.drill.common.expression.ValueExpressions.TimeExpression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal9Expression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal18Expression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal28Expression;
+import org.apache.drill.common.expression.ValueExpressions.Decimal38Expression;
 import org.apache.drill.common.expression.ValueExpressions.IntExpression;
 import org.apache.drill.common.expression.ValueExpressions.QuotedString;
 import org.apache.drill.common.expression.fn.CastFunctions;
@@ -127,24 +131,34 @@ public class ExpressionTreeMaterializer {
       if (matchedFuncHolder!=null) {
         //Compare parm type against arg type. Insert cast on top of arg, whenever necessary.
         for (int i = 0; i < call.args.size(); ++i) {
+
+          LogicalExpression currentArg = call.args.get(i);
+
           TypeProtos.MajorType parmType = matchedFuncHolder.getParmMajorType(i);
 
           //Case 1: If  1) the argument is NullExpression
           //            2) the parameter of matchedFuncHolder allows null input, or func's null_handling is NULL_IF_NULL (means null and non-null are exchangable).
           //        then replace NullExpression with a TypedNullConstant
-          if (call.args.get(i).equals(NullExpression.INSTANCE) &&
+          if (currentArg.equals(NullExpression.INSTANCE) &&
             ( parmType.getMode().equals(TypeProtos.DataMode.OPTIONAL) ||
               matchedFuncHolder.getNullHandling() == FunctionTemplate.NullHandling.NULL_IF_NULL)) {
             argsWithCast.add(new TypedNullConstant(parmType));
-          } else if (Types.softEquals(parmType, call.args.get(i).getMajorType(), matchedFuncHolder.getNullHandling() ==
-            FunctionTemplate.NullHandling.NULL_IF_NULL)) {
+          } else if (Types.softEquals(parmType, currentArg.getMajorType(), matchedFuncHolder.getNullHandling() ==
+                  FunctionTemplate.NullHandling.NULL_IF_NULL)) {
             //Case 2: argument and parameter matches. Do nothing.
-            argsWithCast.add(call.args.get(i));
+            argsWithCast.add(currentArg);
           } else {
             //Case 3: insert cast if param type is different from arg type.
             String castFuncName = CastFunctions.getCastFunc(parmType.getMinorType());
             List<LogicalExpression> castArgs = Lists.newArrayList();
             castArgs.add(call.args.get(i));  //input_expr
+
+            if (parmType.getMinorType().name().startsWith("DECIMAL")) {
+              // Add the scale and precision to the arguments of the implicit cast
+              castArgs.add(new ValueExpressions.LongExpression(currentArg.getMajorType().getPrecision(), null));
+              castArgs.add(new ValueExpressions.LongExpression(currentArg.getMajorType().getScale(), null));
+            }
+
             FunctionCall castCall = new FunctionCall(castFuncName, castArgs, ExpressionPosition.UNKNOWN);
             DrillFuncHolder matchedCastFuncHolder = resolver.getBestMatch(
               registry.getDrillRegistry().getMethods().get(castFuncName), castCall);
@@ -155,6 +169,7 @@ public class ExpressionTreeMaterializer {
             }
 
             argsWithCast.add(new DrillFuncHolderExpr(call.getName(), matchedCastFuncHolder, castArgs, ExpressionPosition.UNKNOWN));
+
           }
         }
         return new DrillFuncHolderExpr(call.getName(), matchedFuncHolder, argsWithCast, call.getPosition());
@@ -263,6 +278,26 @@ public class ExpressionTreeMaterializer {
     }
 
     @Override
+    public LogicalExpression visitDecimal9Constant(Decimal9Expression decExpr, FunctionImplementationRegistry registry) {
+      return decExpr;
+    }
+
+    @Override
+    public LogicalExpression visitDecimal18Constant(Decimal18Expression decExpr, FunctionImplementationRegistry registry) {
+      return decExpr;
+    }
+
+    @Override
+    public LogicalExpression visitDecimal28Constant(Decimal28Expression decExpr, FunctionImplementationRegistry registry) {
+      return decExpr;
+    }
+
+    @Override
+    public LogicalExpression visitDecimal38Constant(Decimal38Expression decExpr, FunctionImplementationRegistry registry) {
+      return decExpr;
+    }
+
+    @Override
     public LogicalExpression visitDoubleConstant(DoubleExpression dExpr, FunctionImplementationRegistry registry) {
       return dExpr;
     }
@@ -288,27 +323,29 @@ public class ExpressionTreeMaterializer {
       
       if(castEqual(e.getPosition(), newMajor, input.getMajorType())) return input; // don't do pointless cast.
       
-      
-      if(newMinor == MinorType.LATE){
-        throw new UnsupportedOperationException("LATE binding is not supported");
-      } else if (newMinor == MinorType.NULL){
-        // convert it into null expression
-        return NullExpression.INSTANCE;
-      }
-
-      // if the type is fully bound, convert to functioncall and materialze the function.
-      MajorType type = e.getMajorType();
-      String castFuncWithType = "cast" + type.getMinorType().name();
-
-      List<LogicalExpression> newArgs = Lists.newArrayList();
-      newArgs.add(e.getInput());  //input_expr
-
-      //VarLen type
-      if (!Types.isFixedWidthType(type)) {
-        newArgs.add(new ValueExpressions.LongExpression(type.getWidth(), null));
+      if(newMinor == MinorType.LATE || newMinor == MinorType.NULL){
+        // if the type still isn't fully bound, leave as cast expression.
+        return new CastExpression(input, e.getMajorType(), e.getPosition());
+      }else{
+        // if the type is fully bound, convert to functioncall and materialze the function.
+        MajorType type = e.getMajorType();
+
+        // Get the cast function name from the map
+        String castFuncWithType = CastFunctions.getCastFunc(type.getMinorType());
+
+        List<LogicalExpression> newArgs = Lists.newArrayList();
+        newArgs.add(e.getInput());  //input_expr
+
+        //VarLen type
+        if (!Types.isFixedWidthType(type)) {
+          newArgs.add(new ValueExpressions.LongExpression(type.getWidth(), null));
+        } else if (type.getMinorType().name().startsWith("DECIMAL")) {
+            newArgs.add(new ValueExpressions.LongExpression(type.getPrecision(), null));
+            newArgs.add(new ValueExpressions.LongExpression(type.getScale(), null));
+        }
+        FunctionCall fc = new FunctionCall(castFuncWithType, newArgs, e.getPosition());
+        return fc.accept(this, value);   
       }
-      FunctionCall fc = new FunctionCall(castFuncWithType, newArgs, e.getPosition());
-      return fc.accept(this, value);
     }
   
     private boolean castEqual(ExpressionPosition pos, MajorType from, MajorType to){
@@ -326,6 +363,16 @@ public class ExpressionTreeMaterializer {
       case UINT8:
         // nothing else matters.
         return true;
+    case DECIMAL9:
+    case DECIMAL18:
+    case DECIMAL28DENSE:
+    case DECIMAL28SPARSE:
+    case DECIMAL38DENSE:
+    case DECIMAL38SPARSE:
+      if (to.getScale() == from.getScale() && to.getPrecision() == from.getPrecision()) {
+        return true;
+      }
+      return false;
 
       case FIXED16CHAR:
       case FIXEDBINARY:

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/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 d91b282..53c9952 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
@@ -51,6 +51,6 @@ public @interface FunctionTemplate {
   }
   
   public static enum FunctionScope{
-    SIMPLE, POINT_AGGREGATE, HOLISTIC_AGGREGATE, RANGE_AGGREGATE;
+    SIMPLE, POINT_AGGREGATE, HOLISTIC_AGGREGATE, RANGE_AGGREGATE, DECIMAL_MAX_SCALE, DECIMAL_SUM_SCALE, DECIMAL_CAST;
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalCastFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalCastFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalCastFuncHolder.java
new file mode 100644
index 0000000..2a0ac0c
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalCastFuncHolder.java
@@ -0,0 +1,68 @@
+/**
+ * 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.exceptions.DrillRuntimeException;
+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.common.types.TypeProtos.MajorType;
+
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+
+public class DrillDecimalCastFuncHolder extends DrillSimpleFuncHolder {
+
+
+    public DrillDecimalCastFuncHolder(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);
+    }
+
+    @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;
+                }
+            }
+        }
+
+        if (args.size() != 3) {
+            StringBuilder err = new StringBuilder();
+            for (int i = 0; i < args.size(); i++) {
+                err.append("arg" + i + ": " + args.get(i).getMajorType().getMinorType());
+            }
+            throw new DrillRuntimeException("Decimal cast function invoked with incorect arguments" + err);
+        }
+
+        int scale = (int) ((ValueExpressions.LongExpression)(args.get(args.size() - 1))).getLong();
+        int precision = (int) ((ValueExpressions.LongExpression)(args.get(args.size() - 2))).getLong();
+        return (TypeProtos.MajorType.newBuilder().setMinorType(returnValue.type.getMinorType()).setScale(scale).setPrecision(precision).setMode(mode).build());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalMaxScaleFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalMaxScaleFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalMaxScaleFuncHolder.java
new file mode 100644
index 0000000..62fa513
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalMaxScaleFuncHolder.java
@@ -0,0 +1,58 @@
+/**
+ * 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.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+
+public class DrillDecimalMaxScaleFuncHolder extends DrillSimpleFuncHolder{
+
+
+    public DrillDecimalMaxScaleFuncHolder(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);
+    }
+
+    @Override
+    public MajorType getReturnType(List<LogicalExpression> args) {
+
+        TypeProtos.DataMode mode = returnValue.type.getMode();
+        int scale = 0;
+        int precision = 0;
+
+        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;
+                }
+                scale = Math.max(scale, e.getMajorType().getScale());
+                precision = Math.max(precision, e.getMajorType().getPrecision());
+            }
+        }
+        return (TypeProtos.MajorType.newBuilder().setMinorType(returnValue.type.getMinorType()).setScale(scale).setPrecision(precision).setMode(mode).build());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumScaleFuncHolder.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumScaleFuncHolder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumScaleFuncHolder.java
new file mode 100644
index 0000000..2e82966
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillDecimalSumScaleFuncHolder.java
@@ -0,0 +1,58 @@
+/**
+ * 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.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+
+public class DrillDecimalSumScaleFuncHolder extends DrillSimpleFuncHolder{
+
+
+    public DrillDecimalSumScaleFuncHolder(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);
+    }
+
+    @Override
+    public MajorType getReturnType(List<LogicalExpression> args) {
+
+        TypeProtos.DataMode mode = returnValue.type.getMode();
+        int scale = 0;
+        int precision = 0;
+
+        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;
+                }
+                scale += e.getMajorType().getScale();
+                precision = Math.max(precision, e.getMajorType().getPrecision());
+            }
+        }
+        return (TypeProtos.MajorType.newBuilder().setMinorType(returnValue.type.getMinorType()).setScale(scale).setPrecision(precision).setMode(mode).build());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/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 0f80d11..888829d 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
@@ -209,7 +209,15 @@ public class FunctionConverter {
       case SIMPLE:
         return new DrillSimpleFuncHolder(template.scope(), template.nulls(), template.isBinaryCommutative(),
           template.isRandom(), registeredNames, ps, outputField, works, methods, imports);
-
+      case DECIMAL_MAX_SCALE:
+          return new DrillDecimalMaxScaleFuncHolder(template.scope(), template.nulls(), template.isBinaryCommutative(),
+                  template.isRandom(), registeredNames, ps, outputField, works, methods, imports);
+      case DECIMAL_SUM_SCALE:
+          return new DrillDecimalSumScaleFuncHolder(template.scope(), template.nulls(), template.isBinaryCommutative(),
+                  template.isRandom(), registeredNames, ps, outputField, works, methods, imports);
+      case DECIMAL_CAST:
+          return new DrillDecimalCastFuncHolder(template.scope(), template.nulls(), template.isBinaryCommutative(),
+                  template.isRandom(), registeredNames, ps, outputField, works, methods, imports);
       case HOLISTIC_AGGREGATE:
       case RANGE_AGGREGATE:
       default:

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
index ad6aa3c..bc2178b 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
@@ -30,8 +30,10 @@ import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.expression.SchemaPath;
 import org.apache.drill.common.expression.ValueExpressions;
 import org.apache.drill.common.types.TypeProtos.MajorType;
+import org.apache.drill.common.types.TypeProtos;
 import org.apache.drill.common.types.TypeProtos.MinorType;
 import org.apache.drill.common.types.Types;
+import org.apache.drill.exec.expr.EvaluationVisitor;
 import org.apache.drill.exec.record.NullExpression;
 import org.eigenbase.rel.RelNode;
 import org.eigenbase.reltype.RelDataTypeField;
@@ -204,15 +206,37 @@ public class DrillOptiq {
       MajorType castType = null;
       
       switch(call.getType().getSqlTypeName().getName()){
-        case "VARCHAR":
-        case "CHAR":
-          castType = Types.required(MinorType.VARCHAR).toBuilder().setWidth(call.getType().getPrecision()).build();
+      case "VARCHAR":
+      case "CHAR":
+        castType = Types.required(MinorType.VARCHAR).toBuilder().setWidth(call.getType().getPrecision()).build();
+        break;
+      
+      case "INTEGER": castType = Types.required(MinorType.INT); break;
+      case "FLOAT": castType = Types.required(MinorType.FLOAT4); break;
+      case "DOUBLE": castType = Types.required(MinorType.FLOAT8); break;
+      case "DECIMAL":
+
+          int precision = call.getType().getPrecision();
+          int scale = call.getType().getScale();
+
+          if (precision <= 9) {
+              castType = TypeProtos.MajorType.newBuilder().setMinorType(MinorType.DECIMAL9).setPrecision(precision).setScale(scale).build();
+          } else if (precision <= 18) {
+              castType = TypeProtos.MajorType.newBuilder().setMinorType(MinorType.DECIMAL18).setPrecision(precision).setScale(scale).build();
+          } else if (precision <= 28) {
+              // Inject a cast to SPARSE before casting to the dense type.
+              castType = TypeProtos.MajorType.newBuilder().setMinorType(MinorType.DECIMAL28SPARSE).setPrecision(precision).setScale(scale).build();
+              arg = FunctionCallFactory.createCast(castType, ExpressionPosition.UNKNOWN, arg);
+              castType = TypeProtos.MajorType.newBuilder().setMinorType(MinorType.DECIMAL28DENSE).setPrecision(precision).setScale(scale).build();
+          } else if (precision <= 38) {
+              castType = TypeProtos.MajorType.newBuilder().setMinorType(MinorType.DECIMAL38SPARSE).setPrecision(precision).setScale(scale).build();
+              arg = FunctionCallFactory.createCast(castType, ExpressionPosition.UNKNOWN, arg);
+              castType = TypeProtos.MajorType.newBuilder().setMinorType(MinorType.DECIMAL38DENSE).setPrecision(precision).setScale(scale).build();
+          } else {
+              throw new UnsupportedOperationException("Only Decimal types with precision range 0 - 38 is supported");
+          }
           break;
       
-        case "INTEGER": castType = Types.required(MinorType.INT); break;
-        case "FLOAT": castType = Types.required(MinorType.FLOAT4); break;
-        case "DOUBLE": castType = Types.required(MinorType.FLOAT8); break;
-        case "DECIMAL": throw new UnsupportedOperationException("Need to add decimal.");
         case "INTERVAL_YEAR_MONTH": castType = Types.required(MinorType.INTERVALYEAR); break;
         case "INTERVAL_DAY_TIME": castType = Types.required(MinorType.INTERVALDAY); break;
         default: castType = Types.required(MinorType.valueOf(call.getType().getSqlTypeName().getName()));
@@ -251,6 +275,20 @@ public class DrillOptiq {
         int a = ((BigDecimal) literal.getValue()).intValue();
         return ValueExpressions.getInt(a);
       case DECIMAL:
+        /* TODO: Enable using Decimal literals once we have more functions implemented for Decimal
+         * For now continue using Double instead of decimals
+
+        int precision = ((BigDecimal) literal.getValue()).precision();
+        if (precision <= 9) {
+            return ValueExpressions.getDecimal9((BigDecimal)literal.getValue());
+        } else if (precision <= 18) {
+            return ValueExpressions.getDecimal18((BigDecimal)literal.getValue());
+        } else if (precision <= 28) {
+            return ValueExpressions.getDecimal28((BigDecimal)literal.getValue());
+        } else if (precision <= 38) {
+            return ValueExpressions.getDecimal38((BigDecimal)literal.getValue());
+        } */
+
         double dbl = ((BigDecimal) literal.getValue()).doubleValue();
         logger.warn("Converting exact decimal into approximate decimal.  Should be fixed once decimal is implemented.");
         return ValueExpressions.getFloat8(dbl);

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/record/MaterializedField.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/MaterializedField.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/MaterializedField.java
index abe6308..a9d53ac 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/MaterializedField.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/MaterializedField.java
@@ -22,9 +22,12 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.expression.PathSegment;
 import org.apache.drill.common.expression.PathSegment.NameSegment;
 import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.logical.data.NamedExpression;
+import org.apache.drill.common.types.TypeProtos;
 import org.apache.drill.common.types.TypeProtos.DataMode;
 import org.apache.drill.common.types.TypeProtos.MajorType;
 import org.apache.drill.exec.expr.TypeHelper;
@@ -123,6 +126,12 @@ public class MaterializedField{
     return def.getMajorType();
   }
 
+  public int getScale() {
+      return def.getMajorType().getScale();
+  }
+  public int getPrecision() {
+      return def.getMajorType().getPrecision();
+  }
   public boolean isNullable() {
     return def.getMajorType().getMode() == DataMode.OPTIONAL;
   }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ResolverTypePrecedence.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ResolverTypePrecedence.java b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ResolverTypePrecedence.java
index 579a07c..f6d83e2 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ResolverTypePrecedence.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ResolverTypePrecedence.java
@@ -58,12 +58,14 @@ public static final Map<MinorType, Integer> precedenceMap;
   	precedenceMap.put(MinorType.BIGINT, i += 2);
   	precedenceMap.put(MinorType.UINT8, i += 2);
   	precedenceMap.put(MinorType.MONEY, i += 2);
-  	precedenceMap.put(MinorType.DECIMAL4, i += 2);
-  	precedenceMap.put(MinorType.DECIMAL8, i += 2);
-  	precedenceMap.put(MinorType.DECIMAL12, i += 2);
-  	precedenceMap.put(MinorType.DECIMAL16, i += 2);
   	precedenceMap.put(MinorType.FLOAT4, i += 2);
   	precedenceMap.put(MinorType.FLOAT8, i += 2);
+ 	precedenceMap.put(MinorType.DECIMAL9, i += 2);
+  	precedenceMap.put(MinorType.DECIMAL18, i += 2);
+   	precedenceMap.put(MinorType.DECIMAL28DENSE, i += 2);
+  	precedenceMap.put(MinorType.DECIMAL28SPARSE, i += 2);
+    precedenceMap.put(MinorType.DECIMAL38DENSE, i += 2);
+    precedenceMap.put(MinorType.DECIMAL38SPARSE, i += 2);
   	precedenceMap.put(MinorType.TIME, i += 2);
   	precedenceMap.put(MinorType.DATE, i += 2);
   	precedenceMap.put(MinorType.TIMESTAMP, i += 2);
@@ -72,7 +74,6 @@ public static final Map<MinorType, Integer> precedenceMap;
     precedenceMap.put(MinorType.INTERVALDAY, i+= 2);
     precedenceMap.put(MinorType.INTERVALYEAR, i+= 2);
     precedenceMap.put(MinorType.INTERVAL, i+= 2);
-
   }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
index 67769c9..2d50846 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
@@ -52,10 +52,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
@@ -74,10 +76,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
@@ -96,10 +100,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
@@ -118,10 +124,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
@@ -134,13 +142,18 @@ public class TypeCastRules {
     rule.add(MinorType.VARBINARY);
     rules.put(MinorType.BIGINT, rule);
 
-    /** DECIMAL4 cast able from **/
+    /** DECIMAL9 cast able from **/
     rule = new HashSet<MinorType>();
     rule.add(MinorType.TINYINT);
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
@@ -151,16 +164,20 @@ public class TypeCastRules {
     rule.add(MinorType.VARCHAR);
     rule.add(MinorType.VAR16CHAR);
     rule.add(MinorType.VARBINARY);
-    rules.put(MinorType.DECIMAL4, rule);
+    rules.put(MinorType.DECIMAL9, rule);
 
-    /** DECIMAL8 cast able from **/
+    /** DECIMAL18 cast able from **/
     rule = new HashSet<MinorType>();
     rule.add(MinorType.TINYINT);
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
@@ -171,17 +188,20 @@ public class TypeCastRules {
     rule.add(MinorType.VARCHAR);
     rule.add(MinorType.VAR16CHAR);
     rule.add(MinorType.VARBINARY);
-    rules.put(MinorType.DECIMAL8, rule);
+    rules.put(MinorType.DECIMAL18, rule);
 
-    /** DECIMAL12 cast able from **/
+    /** DECIMAL28Dense cast able from **/
     rule = new HashSet<MinorType>();
     rule.add(MinorType.TINYINT);
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
@@ -192,18 +212,20 @@ public class TypeCastRules {
     rule.add(MinorType.VARCHAR);
     rule.add(MinorType.VAR16CHAR);
     rule.add(MinorType.VARBINARY);
-    rules.put(MinorType.DECIMAL12, rule);
+    rules.put(MinorType.DECIMAL28DENSE, rule);
 
-    /** DECIMAL16 cast able from **/
+    /** DECIMAL28Sparse cast able from **/
     rule = new HashSet<MinorType>();
     rule.add(MinorType.TINYINT);
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
@@ -214,7 +236,56 @@ public class TypeCastRules {
     rule.add(MinorType.VARCHAR);
     rule.add(MinorType.VAR16CHAR);
     rule.add(MinorType.VARBINARY);
-    rules.put(MinorType.DECIMAL16, rule);
+    rules.put(MinorType.DECIMAL28SPARSE, rule);
+
+    /** DECIMAL38Dense cast able from **/
+    rule = new HashSet<MinorType>();
+    rule.add(MinorType.TINYINT);
+    rule.add(MinorType.SMALLINT);
+    rule.add(MinorType.INT);
+    rule.add(MinorType.BIGINT);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
+    rule.add(MinorType.MONEY);
+    rule.add(MinorType.FLOAT4);
+    rule.add(MinorType.FLOAT8);
+    rule.add(MinorType.BIT);
+    rule.add(MinorType.FIXEDCHAR);
+    rule.add(MinorType.FIXED16CHAR);
+    rule.add(MinorType.FIXEDBINARY);
+    rule.add(MinorType.VARCHAR);
+    rule.add(MinorType.VAR16CHAR);
+    rule.add(MinorType.VARBINARY);
+    rules.put(MinorType.DECIMAL38DENSE, rule);
+
+
+    /** DECIMAL38Sparse cast able from **/
+    rule = new HashSet<MinorType>();
+    rule.add(MinorType.TINYINT);
+    rule.add(MinorType.SMALLINT);
+    rule.add(MinorType.INT);
+    rule.add(MinorType.BIGINT);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
+    rule.add(MinorType.MONEY);
+    rule.add(MinorType.FLOAT4);
+    rule.add(MinorType.FLOAT8);
+    rule.add(MinorType.BIT);
+    rule.add(MinorType.FIXEDCHAR);
+    rule.add(MinorType.FIXED16CHAR);
+    rule.add(MinorType.FIXEDBINARY);
+    rule.add(MinorType.VARCHAR);
+    rule.add(MinorType.VAR16CHAR);
+    rule.add(MinorType.VARBINARY);
+    rules.put(MinorType.DECIMAL38SPARSE, rule);
 
     /** MONEY cast able from **/
     rule = new HashSet<MinorType>();
@@ -222,10 +293,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
@@ -271,10 +344,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.DATE);
     rule.add(MinorType.TIME);
     rule.add(MinorType.TIMESTAMPTZ);
@@ -348,10 +423,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.BIT);
@@ -367,10 +444,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
@@ -387,10 +466,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.TIMESTAMPTZ);
     rule.add(MinorType.FLOAT4);
@@ -410,12 +491,15 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.TIMESTAMPTZ);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
+    rule.add(MinorType.TIMESTAMP);
     rule.add(MinorType.FLOAT4);
     rule.add(MinorType.FLOAT8);
     rule.add(MinorType.BIT);
@@ -440,10 +524,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.TIMESTAMPTZ);
     rule.add(MinorType.FLOAT4);
@@ -470,10 +556,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.TIMESTAMPTZ);
     rule.add(MinorType.FLOAT4);
@@ -491,10 +579,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.TIMESTAMPTZ);
     rule.add(MinorType.FLOAT4);
@@ -521,10 +611,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.TIMESTAMPTZ);
     rule.add(MinorType.FLOAT4);
@@ -551,10 +643,12 @@ public class TypeCastRules {
     rule.add(MinorType.SMALLINT);
     rule.add(MinorType.INT);
     rule.add(MinorType.BIGINT);
-    rule.add(MinorType.DECIMAL4);
-    rule.add(MinorType.DECIMAL8);
-    rule.add(MinorType.DECIMAL12);
-    rule.add(MinorType.DECIMAL16);
+    rule.add(MinorType.DECIMAL9);
+    rule.add(MinorType.DECIMAL18);
+    rule.add(MinorType.DECIMAL28SPARSE);
+    rule.add(MinorType.DECIMAL28DENSE);
+    rule.add(MinorType.DECIMAL38SPARSE);
+    rule.add(MinorType.DECIMAL38DENSE);
     rule.add(MinorType.MONEY);
     rule.add(MinorType.TIMESTAMPTZ);
     rule.add(MinorType.FLOAT4);

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/HiveRecordReader.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/HiveRecordReader.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/HiveRecordReader.java
index c659b1f..d203fa4 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/HiveRecordReader.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/HiveRecordReader.java
@@ -326,7 +326,7 @@ public class HiveRecordReader implements RecordReader {
       case "tinyint":
         return Types.required(TypeProtos.MinorType.TINYINT);
       case "decimal":
-        return Types.required(TypeProtos.MinorType.DECIMAL16);
+        return Types.required(TypeProtos.MinorType.DECIMAL38SPARSE);
       case "double":
         return Types.required(TypeProtos.MinorType.FLOAT8);
       case "float":
@@ -355,7 +355,7 @@ public class HiveRecordReader implements RecordReader {
       case BYTE:
         return Types.required(TypeProtos.MinorType.TINYINT);
       case DECIMAL:
-        return Types.required(TypeProtos.MinorType.DECIMAL16);
+        return Types.required(TypeProtos.MinorType.DECIMAL38SPARSE);
       case DOUBLE:
         return Types.required(TypeProtos.MinorType.FLOAT8);
       case FLOAT:

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/main/java/org/apache/drill/exec/vector/ValueHolderHelper.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/ValueHolderHelper.java b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/ValueHolderHelper.java
index 55d49d1..e4af851 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/ValueHolderHelper.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/ValueHolderHelper.java
@@ -18,14 +18,23 @@
 package org.apache.drill.exec.vector;
 
 import java.nio.ByteOrder;
-
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.SwappedByteBuf;
+import io.netty.buffer.Unpooled;
 import io.netty.buffer.UnpooledByteBufAllocator;
 
+import org.apache.drill.common.util.DecimalUtility;
 import org.apache.drill.exec.expr.holders.VarCharHolder;
 import org.apache.drill.exec.expr.holders.IntervalDayHolder;
+import org.apache.drill.exec.expr.holders.Decimal9Holder;
+import org.apache.drill.exec.expr.holders.Decimal18Holder;
+import org.apache.drill.exec.expr.holders.Decimal28SparseHolder;
+import org.apache.drill.exec.expr.holders.Decimal38SparseHolder;
 
 import com.google.common.base.Charsets;
 
+import java.math.BigDecimal;
+
 
 public class ValueHolderHelper {
   static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ValueHolderHelper.class);
@@ -46,6 +55,63 @@ public class ValueHolderHelper {
 
       dch.days = days;
       dch.milliSeconds = millis;
+      return dch;
+  }
+
+  public static Decimal9Holder getDecimal9Holder(int decimal, int scale, int precision) {
+    Decimal9Holder dch = new Decimal9Holder();
+
+    dch.scale = scale;
+    dch.precision = precision;
+    dch.value = decimal;
+
+    return dch;
+  }
+
+  public static Decimal18Holder getDecimal18Holder(long decimal, int scale, int precision) {
+    Decimal18Holder dch = new Decimal18Holder();
+
+    dch.scale = scale;
+    dch.precision = precision;
+    dch.value = decimal;
+
+    return dch;
+  }
+
+  public static Decimal28SparseHolder getDecimal28Holder(String decimal) {
+
+    Decimal28SparseHolder dch = new Decimal28SparseHolder();
+
+    BigDecimal bigDecimal = new BigDecimal(decimal);
+
+    dch.scale = bigDecimal.scale();
+    dch.precision = bigDecimal.precision();
+    dch.sign = (bigDecimal.signum() == -1);
+    dch.start = 0;
+
+    dch.buffer = Unpooled.wrappedBuffer(new byte[5 * DecimalUtility.integerSize]);
+    dch.buffer = new SwappedByteBuf(dch.buffer);
+    DecimalUtility.getSparseFromBigDecimal(bigDecimal, dch.buffer, dch.start, dch.scale, dch.precision, dch.nDecimalDigits);
+
+    return dch;
+  }
+
+  public static Decimal38SparseHolder getDecimal38Holder(String decimal) {
+
+
+      Decimal38SparseHolder dch = new Decimal38SparseHolder();
+
+      BigDecimal bigDecimal = new BigDecimal(decimal);
+
+      dch.scale = bigDecimal.scale();
+      dch.precision = bigDecimal.precision();
+      dch.sign = (bigDecimal.signum() == -1);
+      dch.start = 0;
+
+
+      dch.buffer = Unpooled.wrappedBuffer(new byte[dch.maxPrecision * DecimalUtility.integerSize]);
+      dch.buffer = new SwappedByteBuf(dch.buffer);
+      DecimalUtility.getSparseFromBigDecimal(bigDecimal, dch.buffer, dch.start, dch.scale, dch.precision, dch.nDecimalDigits);
 
       return dch;
   }