apache / apache/arrow-rs

`variant_get` converts floats and doubles to decimals without checking the target precision

Open
#10,795 1 comment 0 reactions 1 assignee Claimed by @neilconway View on GitHub
bug
Dominant language
Rust
Stars
3.6k
Forks
1.3k
Avg merge
2d 14h
Merged PRs (30d)
167

Description

### Describe the bug

See repro. Similar to #10794

### To Reproduce

```rust
use arrow::array::{ArrayRef, AsArray, Float64Array};
use arrow::compute::cast;
use arrow::datatypes::{DataType, Decimal32Type, DecimalType, Field};
use parquet_variant::Variant;
use parquet_variant_compute::{GetOptions, VariantArrayBuilder, variant_get};
use std::sync::Arc;

let target = DataType::Decimal32(5, 2); // max 999.99

// cast(Float64 -> Decimal32(5, 2)): the value does not fit, so the result is null
let floats: ArrayRef = Arc::new(Float64Array::from(vec![12345.678]));
assert!(cast(&floats, &target).unwrap().is_null(0));

// variant_get with the same values: non-null, out-of-precision results
let mut builder = VariantArrayBuilder::new(2);
builder.append_variant(Variant::Double(12345.678));
builder.append_variant(Variant::Float(12345.678));
let input = ArrayRef::from(builder.build());
let options = GetOptions::new().with_as_type(Some(Arc::new(Field::new("r", target, true))));
let out = variant_get(&input, options).unwrap();
let out = out.as_primitive::();
assert_eq!(out.null_count(), 0);
assert_eq!(out.value(0), 1234568); // 12345.68 in a Decimal32(5, 2) array
assert!(!Decimal32Type::is_valid_decimal_precision(out.value(0), 5));
assert!(!Decimal32Type::is_valid_decimal_precision(out.value(1), 5));
```

### Expected behavior

_No response_

### Additional context

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.