diff --git a/datafusion/core/src/dataframe/mod.rs b/datafusion/core/src/dataframe/mod.rs index be5011cdbfbda..325ae91d27bbf 100644 --- a/datafusion/core/src/dataframe/mod.rs +++ b/datafusion/core/src/dataframe/mod.rs @@ -2439,7 +2439,7 @@ impl DataFrame { } /// Fill null values in specified columns with a given value - /// If no columns are specified (empty vector), applies to all columns + /// If no columns are specified (empty slice), applies to all columns /// Only fills if the value can be cast to the column's type /// /// # Arguments @@ -2458,19 +2458,14 @@ impl DataFrame { /// .read_csv("tests/data/example.csv", CsvReadOptions::new()) /// .await?; /// // Fill nulls in only columns "a" and "c": - /// let df = df.fill_null(ScalarValue::from(0), vec!["a".to_owned(), "c".to_owned()])?; + /// let df = df.fill_null(&ScalarValue::from(0), &["a", "c"])?; /// // Fill nulls across all columns: - /// let df = df.fill_null(ScalarValue::from(0), vec![])?; + /// let df = df.fill_null(&ScalarValue::from(0), &[])?; /// # Ok(()) /// # } /// ``` - #[expect(clippy::needless_pass_by_value)] - pub fn fill_null( - &self, - value: ScalarValue, - columns: Vec, - ) -> Result { - self.fill_columns(&value, &columns, &coalesce(), |_| true) + pub fn fill_null(&self, value: &ScalarValue, columns: &[&str]) -> Result { + self.fill_columns(value, columns, &coalesce(), |_| true) } // Helper to find columns from names diff --git a/datafusion/core/tests/dataframe/mod.rs b/datafusion/core/tests/dataframe/mod.rs index 3b92b92004324..96ffdc9d94e49 100644 --- a/datafusion/core/tests/dataframe/mod.rs +++ b/datafusion/core/tests/dataframe/mod.rs @@ -6472,11 +6472,8 @@ async fn test_fill_null() -> Result<()> { // Use fill_null to replace nulls on each column. let df_filled = df - .fill_null(ScalarValue::Int32(Some(0)), vec!["a".to_string()])? - .fill_null( - ScalarValue::Utf8(Some("default".to_string())), - vec!["b".to_string()], - )?; + .fill_null(&ScalarValue::Int32(Some(0)), &["a"])? + .fill_null(&ScalarValue::Utf8(Some("default".to_string())), &["b"])?; let results = df_filled.collect().await?; assert_snapshot!( @@ -6502,8 +6499,7 @@ async fn test_fill_null_all_columns() -> Result<()> { // Use fill_null to replace nulls on all columns. // Only column "b" will be replaced since ScalarValue::Utf8(Some("default".to_string())) // can be cast to Utf8. - let df_filled = - df.fill_null(ScalarValue::Utf8(Some("default".to_string())), vec![])?; + let df_filled = df.fill_null(&ScalarValue::Utf8(Some("default".to_string())), &[])?; let results = df_filled.clone().collect().await?; @@ -6521,7 +6517,7 @@ async fn test_fill_null_all_columns() -> Result<()> { ); // Fill column "a" null values with a value that cannot be cast to Int32. - let df_filled = df_filled.fill_null(ScalarValue::Int32(Some(0)), vec![])?; + let df_filled = df_filled.fill_null(&ScalarValue::Int32(Some(0)), &[])?; let results = df_filled.collect().await?; assert_snapshot!( diff --git a/docs/source/library-user-guide/upgrading/55.0.0.md b/docs/source/library-user-guide/upgrading/55.0.0.md index 2ebb6952fe04b..3ce7118bbf743 100644 --- a/docs/source/library-user-guide/upgrading/55.0.0.md +++ b/docs/source/library-user-guide/upgrading/55.0.0.md @@ -25,6 +25,48 @@ in this section pertains to features and changes that have already been merged to the main branch and are awaiting release in this version. +### `DataFrame::fill_null` now borrows its arguments + +`DataFrame::fill_null` previously took its arguments by value: + +```rust,ignore +// Before +pub fn fill_null( + &self, + value: ScalarValue, + columns: Vec, +) -> Result +``` + +It now borrows them, matching the signature of the newly added +`DataFrame::fill_nan`: + +```rust,ignore +// After +pub fn fill_null( + &self, + value: &ScalarValue, + columns: &[&str], +) -> Result +``` + +This lets callers pass a borrowed `ScalarValue` and slice literals (or +`&str` column names) without first allocating owned `String`s. + +**Migration guide:** + +Borrow the value and pass a slice of `&str` instead of an owned `Vec`: + +```rust,ignore +// Before +let df = df.fill_null(ScalarValue::from(0), vec!["a".to_owned(), "c".to_owned()])?; +let df = df.fill_null(ScalarValue::from(0), vec![])?; + +// After +let df = df.fill_null(&ScalarValue::from(0), &["a", "c"])?; +let df = df.fill_null(&ScalarValue::from(0), &[])?; +``` + ### `Dialect::AVAILABLE` replaced by `Dialect::available()` `datafusion_common::config::Dialect::AVAILABLE` has been removed. Use