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;
}