Skip to content

variant_get converts strings to decimals without checking the target precision #10794

Description

@neilconway

Describe the bug

See repro.

To Reproduce

use arrow::array::{ArrayRef, AsArray, StringArray};
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(Utf8 -> Decimal32(5, 2)): the value does not fit, so the result is null
let strings: ArrayRef = Arc::new(StringArray::from(vec!["12345.678"]));
assert!(cast(&strings, &target).unwrap().is_null(0));

// variant_get with the same string and target type: a non-null, out-of-precision value
let mut builder = VariantArrayBuilder::new(1);
builder.append_variant(Variant::from("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::<Decimal32Type>();
assert!(!out.is_null(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));

Expected behavior

No response

Additional context

No response

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions