Skip to content

Commit

Permalink
[SPARK-32018][SQL][3.0] UnsafeRow.setDecimal should set null with ove…
Browse files Browse the repository at this point in the history
…rflowed value

partially backport #29026

Closes #29125 from cloud-fan/backport.

Authored-by: Wenchen Fan <wenchen@databricks.com>
Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>
  • Loading branch information
cloud-fan authored and dongjoon-hyun committed Jul 16, 2020
1 parent b745041 commit 9b6bea5
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ public void setDecimal(int ordinal, Decimal value, int precision) {
Platform.putLong(baseObject, baseOffset + cursor, 0L);
Platform.putLong(baseObject, baseOffset + cursor + 8, 0L);

if (value == null) {
if (value == null || !value.changePrecision(precision, value.scale())) {
setNullAt(ordinal);
// keep the offset for future update
Platform.putLong(baseObject, getFieldOffset(ordinal), cursor << 32);
Expand Down
10 changes: 10 additions & 0 deletions sql/core/src/test/scala/org/apache/spark/sql/UnsafeRowSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,14 @@ class UnsafeRowSuite extends SparkFunSuite {
// Makes sure hashCode on unsafe array won't crash
unsafeRow.getArray(0).hashCode()
}

test("SPARK-32018: setDecimal with overflowed value") {
val d1 = new Decimal().set(BigDecimal("10000000000000000000")).toPrecision(38, 18)
val row = InternalRow.apply(d1)
val unsafeRow = UnsafeProjection.create(Array[DataType](DecimalType(38, 18))).apply(row)
assert(unsafeRow.getDecimal(0, 38, 18) === d1)
val d2 = (d1 * Decimal(10)).toPrecision(39, 18)
unsafeRow.setDecimal(0, d2, 38)
assert(unsafeRow.getDecimal(0, 38, 18) === null)
}
}

0 comments on commit 9b6bea5

Please sign in to comment.