diff --git a/crates/polars-ops/src/series/ops/floor_divide.rs b/crates/polars-ops/src/series/ops/floor_divide.rs index 73ac9a51019f..87d5994d8f75 100644 --- a/crates/polars-ops/src/series/ops/floor_divide.rs +++ b/crates/polars-ops/src/series/ops/floor_divide.rs @@ -52,5 +52,5 @@ pub fn floor_div_series(a: &Series, b: &Series) -> PolarsResult { floor_div_ca(a, b).into_series() }); - out.cast(logical_type) + unsafe { out.from_physical_unchecked(logical_type) } } diff --git a/crates/polars-ops/src/series/ops/horizontal.rs b/crates/polars-ops/src/series/ops/horizontal.rs index 2e96ab27394a..e02574cd984e 100644 --- a/crates/polars-ops/src/series/ops/horizontal.rs +++ b/crates/polars-ops/src/series/ops/horizontal.rs @@ -107,10 +107,12 @@ fn min_max_binary_columns(left: &Column, right: &Column, min: bool) -> PolarsRes let a: &ChunkedArray<$T> = lhs.as_ref().as_ref().as_ref(); let b: &ChunkedArray<$T> = rhs.as_ref().as_ref().as_ref(); - if min { - min_binary(a, b).into_series().cast(logical) - } else { - max_binary(a, b).into_series().cast(logical) + unsafe { + if min { + min_binary(a, b).into_series().from_physical_unchecked(logical) + } else { + max_binary(a, b).into_series().from_physical_unchecked(logical) + } } }) .map(Column::from) diff --git a/crates/polars-plan/src/dsl/function_expr/shift_and_fill.rs b/crates/polars-plan/src/dsl/function_expr/shift_and_fill.rs index 4dafb71643bf..5890edf1c930 100644 --- a/crates/polars-plan/src/dsl/function_expr/shift_and_fill.rs +++ b/crates/polars-plan/src/dsl/function_expr/shift_and_fill.rs @@ -85,9 +85,11 @@ pub(super) fn shift_and_fill(args: &[Column]) -> PolarsResult { AnyValue::Null => None, v => polars_bail!(ComputeError: "fill value '{}' is not supported", v), }; - ca.shift_and_fill(n, fill_value.as_ref()) - .into_column() - .cast(logical) + unsafe { + ca.shift_and_fill(n, fill_value.as_ref()) + .into_column() + .from_physical_unchecked(logical) + } }, #[cfg(feature = "object")] Object(_, _) => shift_and_fill_with_mask(s, n, fill_value_s), @@ -102,7 +104,7 @@ pub(super) fn shift_and_fill(args: &[Column]) -> PolarsResult { }}; } let out = downcast_as_macro_arg_physical!(physical, dispatch, n, fill_value); - out.cast(logical) + unsafe { out.from_physical_unchecked(logical) } }, dt => polars_bail!(opq = shift_and_fill, dt), } diff --git a/py-polars/tests/unit/datatypes/test_decimal.py b/py-polars/tests/unit/datatypes/test_decimal.py index 2dcd880d43b9..ec0f5eaf9be9 100644 --- a/py-polars/tests/unit/datatypes/test_decimal.py +++ b/py-polars/tests/unit/datatypes/test_decimal.py @@ -581,3 +581,28 @@ def test_decimal_arithmetic_schema_float_20369() -> None: assert_series_equal( (1.0 * s), pl.Series("literal", [1.0], dtype=pl.Decimal(None, 4)) ) + + +def test_decimal_horizontal_20482() -> None: + b = pl.LazyFrame( + { + "a": [D("123.000000"), D("234.000000")], + "b": [D("123.000000"), D("234.000000")], + }, + schema={ + "a": pl.Decimal(18, 6), + "b": pl.Decimal(18, 6), + }, + ) + + assert ( + b.select( + min=pl.min_horizontal(pl.col("a"), pl.col("b")), + max=pl.max_horizontal(pl.col("a"), pl.col("b")), + sum=pl.sum_horizontal(pl.col("a"), pl.col("b")), + ).collect() + ).to_dict(as_series=False) == { + "min": [D("123.000000"), D("234.000000")], + "max": [D("123.000000"), D("234.000000")], + "sum": [D("246.000000"), D("468.000000")], + }