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