diff --git common/src/java/org/apache/hadoop/hive/common/type/Decimal128.java common/src/java/org/apache/hadoop/hive/common/type/Decimal128.java index 94d7bb4..bbaef03 100644 --- common/src/java/org/apache/hadoop/hive/common/type/Decimal128.java +++ common/src/java/org/apache/hadoop/hive/common/type/Decimal128.java @@ -1602,6 +1602,34 @@ public long longValue() { } /** + * Returns long value with fractional part discarded. This matches HiveDecimal semantics. + */ + public long longValueDiscardFractionDestructive(UnsignedInt128 scratchUnsignedInt128) { + if (signum == 0) { + return 0L; + } + + long ret; + if (scale > 0) { + /* + * Divide by a power of 10 equal to 10**scale to logically shift the digits + * places right by "scale" positions to discard them. + */ + UnsignedInt128 powerTenDivisor = SqlMathUtil.POWER_TENS_INT128[scale]; + this.getUnscaledValue().divideDestructive(powerTenDivisor, scratchUnsignedInt128); + } + ret = this.unscaledValue.getV1(); + ret <<= 32L; + ret |= SqlMathUtil.LONG_MASK & this.unscaledValue.getV0(); + + if (signum >= 0) { + return ret; + } else { + return -ret; + } + } + + /** * Converts this {@code Decimal128} to an {@code int}. This conversion is * analogous to the narrowing primitive conversion from {@code double} * to {@code short} as defined in section 5.1.3 of The Java™ diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToLong.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToLong.java index d5f34d5..18c2553b 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToLong.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToLong.java @@ -18,6 +18,8 @@ package org.apache.hadoop.hive.ql.exec.vector.expressions; +import org.apache.hadoop.hive.common.type.Decimal128; +import org.apache.hadoop.hive.common.type.UnsignedInt128; import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector; import org.apache.hadoop.hive.ql.exec.vector.LongColumnVector; @@ -27,6 +29,9 @@ public class CastDecimalToLong extends FuncDecimalToLong { private static final long serialVersionUID = 1L; + private Decimal128 scratchDecimal = new Decimal128(); + private UnsignedInt128 scratchUnsigned = new UnsignedInt128(); + public CastDecimalToLong() { super(); } @@ -37,6 +42,7 @@ public CastDecimalToLong(int inputColumn, int outputColumn) { @Override protected void func(LongColumnVector outV, DecimalColumnVector inV, int i) { - outV.vector[i] = inV.vector[i].longValue(); + scratchDecimal.update(inV.vector[i]); + outV.vector[i] = scratchDecimal.longValueDiscardFractionDestructive(scratchUnsigned); } }