Skip to content

Commit 09e58a4

Browse files
authored
fix: serialization of decimal (#5801)
1 parent 12f57af commit 09e58a4

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

arrow-json/src/reader/decimal_array.rs

+26
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,32 @@ where
6464
let value = parse_decimal::<D>(s, self.precision, self.scale)?;
6565
builder.append_value(value)
6666
}
67+
TapeElement::I64(high) => match tape.get(*p + 1) {
68+
TapeElement::I32(low) => {
69+
let val = ((high as i64) << 32 | (low as u32) as i64).to_string();
70+
let value = parse_decimal::<D>(&val, self.precision, self.scale)?;
71+
builder.append_value(value)
72+
}
73+
_ => unreachable!(),
74+
},
75+
TapeElement::I32(val) => {
76+
let s = val.to_string();
77+
let value = parse_decimal::<D>(&s, self.precision, self.scale)?;
78+
builder.append_value(value)
79+
}
80+
TapeElement::F64(high) => match tape.get(*p + 1) {
81+
TapeElement::F32(low) => {
82+
let val = f64::from_bits((high as u64) << 32 | low as u64).to_string();
83+
let value = parse_decimal::<D>(&val, self.precision, self.scale)?;
84+
builder.append_value(value)
85+
}
86+
_ => unreachable!(),
87+
},
88+
TapeElement::F32(val) => {
89+
let s = f32::from_bits(val).to_string();
90+
let value = parse_decimal::<D>(&s, self.precision, self.scale)?;
91+
builder.append_value(value)
92+
}
6793
_ => return Err(tape.error(*p, "decimal")),
6894
}
6995
}

arrow-json/src/reader/mod.rs

+24
Original file line numberDiff line numberDiff line change
@@ -2212,6 +2212,30 @@ mod tests {
22122212
assert_eq!(values.values(), &[1681319393, -7200]);
22132213
}
22142214

2215+
#[test]
2216+
fn test_serialize_decimal() {
2217+
let json = vec![
2218+
json!({"decimal": 1.234}),
2219+
json!({"decimal": "1.234"}),
2220+
json!({"decimal": 1234}),
2221+
json!({"decimal": "1234"}),
2222+
];
2223+
let schema = Schema::new(vec![Field::new(
2224+
"decimal",
2225+
DataType::Decimal128(10, 3),
2226+
true,
2227+
)]);
2228+
let mut decoder = ReaderBuilder::new(Arc::new(schema))
2229+
.build_decoder()
2230+
.unwrap();
2231+
decoder.serialize(&json).unwrap();
2232+
let batch = decoder.flush().unwrap().unwrap();
2233+
assert_eq!(batch.num_rows(), 4);
2234+
assert_eq!(batch.num_columns(), 1);
2235+
let values = batch.column(0).as_primitive::<Decimal128Type>();
2236+
assert_eq!(values.values(), &[1234, 1234, 1234000, 1234000]);
2237+
}
2238+
22152239
#[test]
22162240
fn test_serde_field() {
22172241
let field = Field::new("int", DataType::Int32, true);

0 commit comments

Comments
 (0)