Skip to content

Commit bcadfeb

Browse files
authored
Remove direct arrow2 exposure (#698)
arrow2 is deprecated: jorgecarleitao/arrow2#1429 Breaking change: - Still supported: batch-by-batch processing as DataFrames via `query_polars()`. That preserves the common Polars flow, including streaming over batches without collecting everything first. - Still supported: raw Arrow-rs access via `step()`. - No longer supported: "give me the raw Polars-arrow/arrow2 batch and let me do my own low-level conversion or array operations on that type". That was the unique role of `step2()`.
2 parents bb3086a + 25c9461 commit bcadfeb

File tree

7 files changed

+36
-40
lines changed

7 files changed

+36
-40
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ num = { version = "0.4", default-features = false }
4242
num-integer = "0.1.46"
4343
pkg-config = "0.3.24"
4444
polars = "0.49.1"
45-
polars-arrow = "0.49.1"
4645
polars-core = "0.49.1"
4746
pretty_assertions = "1.4.1"
4847
prettyplease = "0.2.20"

crates/duckdb/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ vtab-full = ["vtab-excel", "vtab-arrow", "appender-arrow"]
3333
extensions-full = ["json", "parquet", "vtab-full"]
3434
buildtime_bindgen = ["libduckdb-sys/buildtime_bindgen"]
3535
modern-full = ["chrono", "serde_json", "url", "r2d2", "uuid", "polars"]
36-
polars = ["dep:polars", "dep:polars-arrow"]
36+
polars = ["dep:polars", "dep:polars-core"]
3737
# Warning: experimental feature
3838
loadable-extension = ["vtab", "duckdb-loadable-macros", "libduckdb-sys/loadable-extension"]
3939

@@ -50,7 +50,7 @@ libduckdb-sys = { workspace = true }
5050
num = { workspace = true, features = ["std"], optional = true }
5151
num-integer = { workspace = true }
5252
polars = { workspace = true, features = ["dtype-full"], optional = true }
53-
polars-arrow = { workspace = true, optional = true }
53+
polars-core = { workspace = true, optional = true }
5454
r2d2 = { workspace = true, optional = true }
5555
rust_decimal = { workspace = true }
5656
serde_json = { workspace = true, optional = true }

crates/duckdb/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ pub use arrow;
9595
pub use duckdb_loadable_macros::duckdb_entrypoint_c_api;
9696
#[cfg(feature = "polars")]
9797
pub use polars;
98-
#[cfg(feature = "polars")]
99-
pub use polars_arrow as arrow2;
10098

10199
/// The core module contains the main functionality of the DuckDB crate.
102100
pub mod core;

crates/duckdb/src/polars_dataframe.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ impl<'stmt> Iterator for Polars<'stmt> {
2626
type Item = DataFrame;
2727

2828
fn next(&mut self) -> Option<Self::Item> {
29-
let struct_array = self.stmt?.step2()?;
30-
let df = DataFrame::try_from(struct_array).expect("Failed to construct DataFrame from StructArray");
29+
let struct_array = self.stmt?.step_polars()?;
30+
let df = DataFrame::try_from(struct_array)
31+
.unwrap_or_else(|e| panic!("Failed to construct DataFrame from StructArray: {e}"));
3132

3233
Some(df)
3334
}

crates/duckdb/src/raw_statement.rs

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use arrow::{
77
};
88

99
use super::{Result, ffi};
10-
#[cfg(feature = "polars")]
11-
use crate::arrow2;
1210
use crate::{Error, core::LogicalTypeHandle, error::result_from_duckdb_arrow};
11+
#[cfg(feature = "polars")]
12+
use polars_core::utils::arrow as polars_arrow;
1313

1414
/// Private newtype for DuckDB prepared statements that finalize themselves when dropped.
1515
///
@@ -165,54 +165,52 @@ impl RawStatement {
165165

166166
#[cfg(feature = "polars")]
167167
#[inline]
168-
pub fn step2(&self) -> Option<arrow2::array::StructArray> {
169-
self.result?;
168+
pub(crate) fn step_polars(&self) -> Option<polars_arrow::array::StructArray> {
169+
let result = self.result?;
170170

171171
unsafe {
172-
let mut ffi_arrow2_array = arrow2::ffi::ArrowArray::empty();
172+
let mut ffi_arrow_array = polars_arrow::ffi::ArrowArray::empty();
173173

174174
if ffi::duckdb_query_arrow_array(
175-
self.result_unwrap(),
176-
&mut std::ptr::addr_of_mut!(ffi_arrow2_array) as *mut _ as *mut ffi::duckdb_arrow_array,
175+
result,
176+
&mut std::ptr::addr_of_mut!(ffi_arrow_array) as *mut _ as *mut ffi::duckdb_arrow_array,
177177
)
178178
.ne(&ffi::DuckDBSuccess)
179179
{
180180
return None;
181181
}
182182

183-
let mut ffi_arrow2_schema = arrow2::ffi::ArrowSchema::empty();
183+
let mut ffi_arrow_schema = polars_arrow::ffi::ArrowSchema::empty();
184184

185185
if ffi::duckdb_query_arrow_schema(
186-
self.result_unwrap(),
187-
&mut std::ptr::addr_of_mut!(ffi_arrow2_schema) as *mut _ as *mut ffi::duckdb_arrow_schema,
186+
result,
187+
&mut std::ptr::addr_of_mut!(ffi_arrow_schema) as *mut _ as *mut ffi::duckdb_arrow_schema,
188188
)
189189
.ne(&ffi::DuckDBSuccess)
190190
{
191191
return None;
192192
}
193193

194-
let arrow2_field =
195-
arrow2::ffi::import_field_from_c(&ffi_arrow2_schema).expect("Failed to import arrow2 Field from C");
196-
let import_arrow2_array = arrow2::ffi::import_array_from_c(ffi_arrow2_array, arrow2_field.dtype);
197-
198-
if let Err(err) = import_arrow2_array {
199-
// When array is empty, import_array_from_c returns error with message
200-
// "ComputeError("An ArrowArray of type X must have non-null children")
201-
// Therefore, we return None when encountering this error.
202-
match err {
203-
polars::error::PolarsError::ComputeError(_) => return None,
204-
_ => panic!("Failed to import arrow2 Array from C: {err}"),
205-
}
206-
}
194+
let field =
195+
polars_arrow::ffi::import_field_from_c(&ffi_arrow_schema).expect("Failed to import Polars Arrow field");
196+
let import_array = polars_arrow::ffi::import_array_from_c(ffi_arrow_array, field.dtype);
207197

208-
let arrow2_array = import_arrow2_array.unwrap();
209-
let arrow2_struct_array = arrow2_array
198+
let array = match import_array {
199+
Ok(array) => array,
200+
// When array is empty, import_array_from_c returns ComputeError with message
201+
// "An ArrowArray of type X must have non-null children".
202+
Err(polars::error::PolarsError::ComputeError(msg)) if msg.to_string().contains("non-null children") => {
203+
return None;
204+
}
205+
Err(err) => panic!("Failed to import Polars Arrow array from C: {err}"),
206+
};
207+
let struct_array = array
210208
.as_any()
211-
.downcast_ref::<arrow2::array::StructArray>()
212-
.expect("Failed to downcast arrow2 Array to arrow2 StructArray")
209+
.downcast_ref::<polars_arrow::array::StructArray>()
210+
.expect("Failed to downcast Polars Arrow array to StructArray")
213211
.to_owned();
214212

215-
Some(arrow2_struct_array)
213+
Some(struct_array)
216214
}
217215
}
218216

crates/duckdb/src/statement.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ use std::{convert, ffi::c_void, fmt, mem, os::raw::c_char, ptr, str};
33
use arrow::{array::StructArray, datatypes::SchemaRef};
44

55
use super::{AndThenRows, Connection, Error, MappedRows, Params, RawStatement, Result, Row, Rows, ValueRef, ffi};
6+
#[cfg(feature = "polars")]
7+
use crate::polars_dataframe::Polars;
68
use crate::{
79
arrow_batch::{Arrow, ArrowStream},
810
error::result_from_duckdb_prepare,
911
types::{ToSql, ToSqlOutput},
1012
};
1113
#[cfg(feature = "polars")]
12-
use crate::{arrow2, polars_dataframe::Polars};
14+
use polars_core::utils::arrow as polars_arrow;
1315

1416
/// A prepared statement.
1517
///
@@ -403,10 +405,9 @@ impl Statement<'_> {
403405
}
404406

405407
#[cfg(feature = "polars")]
406-
/// Get next batch records in arrow2
407408
#[inline]
408-
pub fn step2(&self) -> Option<arrow2::array::StructArray> {
409-
self.stmt.step2()
409+
pub(crate) fn step_polars(&self) -> Option<polars_arrow::array::StructArray> {
410+
self.stmt.step_polars()
410411
}
411412

412413
#[inline]

0 commit comments

Comments
 (0)