Skip to content

Commit

Permalink
fix: Raise on oob decimal precision (#17445)
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchie46 committed Jul 5, 2024
1 parent 221bea8 commit a539d88
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 6 deletions.
2 changes: 1 addition & 1 deletion crates/polars-core/src/chunked_array/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub(crate) fn cast_chunks(
let check_nulls = matches!(options, CastOptions::Strict);
let options = options.into();

let arrow_dtype = dtype.to_arrow(true);
let arrow_dtype = dtype.try_to_arrow(true)?;
chunks
.iter()
.map(|arr| {
Expand Down
15 changes: 10 additions & 5 deletions crates/polars-core/src/datatypes/dtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub enum DataType {
Float64,
/// Fixed point decimal type optional precision and non-negative scale.
/// This is backed by a signed 128-bit integer which allows for up to 38 significant digits.
/// Meaning max precision is 38.
#[cfg(feature = "dtype-decimal")]
Decimal(Option<usize>, Option<usize>), // precision/scale; scale being None means "infer"
/// String data
Expand Down Expand Up @@ -542,11 +543,15 @@ impl DataType {
Float32 => Ok(ArrowDataType::Float32),
Float64 => Ok(ArrowDataType::Float64),
#[cfg(feature = "dtype-decimal")]
// note: what else can we do here other than setting precision to 38?..
Decimal(precision, scale) => Ok(ArrowDataType::Decimal(
(*precision).unwrap_or(38),
scale.unwrap_or(0), // and what else can we do here?
)),
Decimal(precision, scale) => {
let precision = (*precision).unwrap_or(38);
polars_ensure!(precision <= 38 && precision > 0, InvalidOperation: "decimal precision should be <= 38 & >= 1");

Ok(ArrowDataType::Decimal(
precision,
scale.unwrap_or(0), // and what else can we do here?
))
},
String => {
let dt = if pl_flavor {
ArrowDataType::Utf8View
Expand Down
7 changes: 7 additions & 0 deletions py-polars/tests/unit/datatypes/test_decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,10 @@ def test_decimal_supertype() -> None:
pl.col("column_0").cast(pl.Decimal(scale=6)) * 1
)
assert q.collect().dtypes[0].is_decimal()


def test_decimal_raise_oob_precision() -> None:
df = pl.DataFrame({"a": [1.0]})
# max precision is 38.
with pytest.raises(pl.exceptions.InvalidOperationError):
df.select(b=pl.col("a").cast(pl.Decimal(76, 38)))

0 comments on commit a539d88

Please sign in to comment.