pola-rs/polars · error
not implemented
Error message
not implemented
What it means
`ArrowDataType::underlying_physical_type()` (crates/polars-arrow/src/datatypes/mod.rs) maps logical types to their physical representation. The `Decimal256(_, _)` arm on line 351 is `unimplemented!()` because polars-arrow has no 256-bit NativeType, and the sibling `Interval(MonthDayNano | MonthDayMillis)` arm is likewise unimplemented. Asking for the physical layout of these types panics with 'not implemented'.
Solutions
- Convert Decimal256 columns to Decimal128 (or float/string) at the source before interop with polars.
- Reject or drop such columns at schema-inspection time when reading foreign Arrow data.
- Guard: check `!matches!(dtype, Decimal256(_, _) | Interval(IntervalUnit::MonthDayNano | IntervalUnit::MonthDayMillis))` before touching physical layout.
- Track polars' support status — if a later release adds these arms, upgrade.
Example fix
// before
let phys = dtype.underlying_physical_type(); // panics for Decimal256 / MonthDayNano
// after
use polars_arrow::datatypes::{ArrowDataType, IntervalUnit};
fn has_physical(dtype: &ArrowDataType) -> bool {
!matches!(
dtype,
ArrowDataType::Decimal256(_, _)
| ArrowDataType::Interval(IntervalUnit::MonthDayNano | IntervalUnit::MonthDayMillis)
)
}
assert!(has_physical(dtype), "unsupported physical layout for {dtype:?}"); Defensive patterns
Strategy: type-guard
Validate before calling
use polars_arrow::datatypes::{ArrowDataType, IntervalUnit};
fn assert_physical_resolvable(dtype: &ArrowDataType) -> polars_error::PolarsResult<()> {
if matches!(dtype, ArrowDataType::Decimal256(_, _) | ArrowDataType::Interval(IntervalUnit::MonthDayNano | IntervalUnit::MonthDayMillis)) {
polars_bail!(InvalidOperation: "no physical type for {dtype:?}");
}
Ok(())
} Type guard
fn has_physical_type(dtype: &ArrowDataType) -> bool {
use ArrowDataType::*;
!matches!(
dtype,
Decimal256(_, _) | Union(_) | Map(_, _)
| Interval(IntervalUnit::MonthDayNano | IntervalUnit::MonthDayMillis)
)
} Try / catch
let phys = std::panic::catch_unwind(|| dtype.underlying_physical_type())
.map_err(|_| polars_err!(InvalidOperation: "physical type unimplemented for {dtype:?}"))?; Prevention
- Convert decimal(38+) to decimal(<=38) or float at the producing system before interop with polars.
- Whitelist dtypes when reading foreign Arrow schemas and reject Decimal256/interval variants early.
- Remember Union and Map also panic in this function.
When it happens
Trigger: Calling `dtype.underlying_physical_type()` (directly or via `to_physical_type()` consumers such as serialization, kernels, and FFI dispatch) on a `Decimal256` dtype or an `Interval` with MonthDayNano/MonthDayMillis unit. These dtypes typically arrive by importing Arrow IPC/FFI schemas from implementations that do support them (pyarrow, arrow-rs).
Common situations: Cross-implementation interop: reading files containing decimal(38+, s) or month-day-nano interval columns produced by pyarrow/arrow-rs, then running any polars operation that needs the physical type. Polars supports Decimal128 (`Decimal(_, _) => Int128`) but not Decimal256, and only YearMonth/DayTime intervals.
Related errors
AI-assisted analysis of pola-rs/polars@68506541d2 (2026-08-19).
Data as JSON: /api/errors/ee43767fd42ef160.
Report an issue: GitHub.
Appendix: source
Thrown at crates/polars-arrow/src/datatypes/mod.rs:351
// The datatype underlying this (possibly logical) arrow data type.
pub fn underlying_physical_type(&self) -> ArrowDataType {
use ArrowDataType::*;
match self {
Null | Boolean | Int8 | Int16 | Int32 | Int64 | Int128 | UInt8 | UInt16 | UInt32
| UInt64 | UInt128 | Float16 | Float32 | Float64 | Binary | LargeBinary | Utf8
| LargeUtf8 | BinaryView | Utf8View | FixedSizeBinary(_) | Unknown => self.clone(),
Decimal32(_, _) | Date32 | Time32(_) | Interval(IntervalUnit::YearMonth) => Int32,
Decimal64(_, _)
| Date64
| Timestamp(_, _)
| Time64(_)
| Duration(_)
| Interval(IntervalUnit::DayTime) => Int64,
Interval(IntervalUnit::MonthDayNano | IntervalUnit::MonthDayMillis) => unimplemented!(),
Decimal(_, _) => Int128,
Decimal256(_, _) => unimplemented!(),
List(field) => List(Box::new(
field.with_dtype(field.dtype.underlying_physical_type()),
)),
LargeList(field) => LargeList(Box::new(
field.with_dtype(field.dtype.underlying_physical_type()),
)),
FixedSizeList(field, width) => FixedSizeList(
Box::new(field.with_dtype(field.dtype.underlying_physical_type())),
*width,
),
Struct(fields) => Struct(
fields
.iter()
.map(|field| field.with_dtype(field.dtype.underlying_physical_type()))
.collect(),
),
Dictionary(keys, _, _) => (*keys).into(),
Union(_) => unimplemented!(),View on GitHub (pinned to 68506541d2)