Skip to content

Commit 5083d39

Browse files
authored
Merge pull request #37 from wangfenjin/arrow-schema
add get_schema api
2 parents 762fec6 + c28268e commit 5083d39

File tree

4 files changed

+25
-22
lines changed

4 files changed

+25
-22
lines changed

src/arrow_batch.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::Statement;
2-
use arrow::record_batch::RecordBatch;
2+
use arrow::{datatypes::SchemaRef, record_batch::RecordBatch};
33

44
/// An handle for the resulting RecordBatch of a query.
55
#[must_use = "Arrow is lazy and will do nothing unless consumed"]
@@ -12,6 +12,12 @@ impl<'stmt> Arrow<'stmt> {
1212
pub(crate) fn new(stmt: &'stmt Statement<'stmt>) -> Arrow<'stmt> {
1313
Arrow { stmt: Some(stmt) }
1414
}
15+
16+
/// return arrow schema
17+
#[inline]
18+
pub fn get_schema(&self) -> SchemaRef {
19+
self.stmt.unwrap().stmt.schema()
20+
}
1521
}
1622

1723
impl<'stmt> Iterator for Arrow<'stmt> {

src/column.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@ impl Statement<'_> {
2929
/// If associated DB schema can be altered concurrently, you should make
3030
/// sure that current statement has already been stepped once before
3131
/// calling this method.
32-
pub fn column_names(&self) -> Vec<&String> {
33-
self.stmt.schema().fields().iter().map(|f| f.name()).collect()
32+
pub fn column_names(&self) -> Vec<String> {
33+
self.stmt
34+
.schema()
35+
.fields()
36+
.iter()
37+
.map(|f| f.name().to_owned())
38+
.collect()
3439
}
3540

3641
/// Return the number of columns in the result set returned by the prepared

src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ mod test {
528528
use std::fmt;
529529

530530
use arrow::array::Int32Array;
531+
use arrow::datatypes::DataType;
531532
use arrow::record_batch::RecordBatch;
532533
use fallible_iterator::FallibleIterator;
533534

@@ -635,7 +636,7 @@ mod test {
635636
let filename = "no_such_file.db";
636637
let result =
637638
Connection::open_with_flags(filename, Config::default().access_mode(config::AccessMode::ReadOnly)?);
638-
assert!(!result.is_ok());
639+
assert!(result.is_err());
639640
let err = result.err().unwrap();
640641
if let Error::DuckDBFailure(_e, Some(msg)) = err {
641642
// TODO: update error code
@@ -1180,6 +1181,11 @@ mod test {
11801181
let mut stmt = db.prepare("select t from test order by t desc")?;
11811182
let mut arr = stmt.query_arrow([])?;
11821183

1184+
let schema = arr.get_schema();
1185+
assert_eq!(schema.fields().len(), 1);
1186+
assert_eq!(schema.field(0).name(), "t");
1187+
assert_eq!(schema.field(0).data_type(), &DataType::Int32);
1188+
11831189
let rb = arr.next().unwrap();
11841190
let column = rb.column(0).as_any().downcast_ref::<Int32Array>().unwrap();
11851191
assert_eq!(column.len(), 5);

src/raw_statement.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use arrow::ffi::{ArrowArray, FFI_ArrowArray, FFI_ArrowSchema};
1818
pub struct RawStatement {
1919
ptr: ffi::duckdb_prepared_statement,
2020
result: Option<ffi::duckdb_arrow>,
21-
c_schema: Option<*const FFI_ArrowSchema>,
2221
schema: Option<SchemaRef>,
2322
}
2423

@@ -28,7 +27,6 @@ impl RawStatement {
2827
RawStatement {
2928
ptr: stmt,
3029
result: None,
31-
c_schema: None,
3230
schema: None,
3331
}
3432
}
@@ -60,11 +58,6 @@ impl RawStatement {
6058
let (mut arrays, mut schema) = ArrowArray::into_raw(ArrowArray::empty());
6159
let schema = &mut schema;
6260
let arrays = &mut arrays;
63-
// TODO: Can we reuse schema?
64-
// destroy schema as we don't need it...
65-
// Arc::from_raw(schema);
66-
// TODO: use this after https://github.com/apache/arrow-rs/pull/612
67-
// let mut arrays = Arc::into_raw(Arc::new(FFI_ArrowArray::empty()));
6861
if ffi::duckdb_query_arrow_array(self.result_unwrap(), arrays as *mut _ as *mut *mut c_void)
6962
!= ffi::DuckDBSuccess
7063
{
@@ -104,8 +97,8 @@ impl RawStatement {
10497
}
10598

10699
#[inline]
107-
pub fn schema(&self) -> &SchemaRef {
108-
self.schema.as_ref().unwrap()
100+
pub fn schema(&self) -> SchemaRef {
101+
self.schema.clone().unwrap()
109102
}
110103

111104
#[inline]
@@ -161,14 +154,13 @@ impl RawStatement {
161154

162155
let rows_changed = ffi::duckdb_arrow_rows_changed(out);
163156
let mut c_schema = Arc::into_raw(Arc::new(FFI_ArrowSchema::empty()));
164-
let schema = &mut c_schema;
165-
let rc = ffi::duckdb_query_arrow_schema(out, schema as *mut _ as *mut *mut c_void);
157+
let rc = ffi::duckdb_query_arrow_schema(out, &mut c_schema as *mut _ as *mut *mut c_void);
166158
if rc != ffi::DuckDBSuccess {
167159
Arc::from_raw(c_schema);
168160
result_from_duckdb_arrow(rc, out)?;
169161
}
170162
self.schema = Some(Arc::new(Schema::try_from(&*c_schema).unwrap()));
171-
self.c_schema = Some(c_schema);
163+
Arc::from_raw(c_schema);
172164

173165
self.result = Some(out);
174166
Ok(rows_changed as usize)
@@ -178,12 +170,6 @@ impl RawStatement {
178170
#[inline]
179171
pub fn reset_result(&mut self) {
180172
self.schema = None;
181-
if self.c_schema.is_some() {
182-
unsafe {
183-
Arc::from_raw(self.c_schema.unwrap());
184-
}
185-
self.c_schema = None;
186-
}
187173
if self.result.is_some() {
188174
unsafe {
189175
ffi::duckdb_destroy_arrow(&mut self.result_unwrap());

0 commit comments

Comments
 (0)