datafusion_ffi/
arrow_wrappers.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use std::sync::Arc;
19
20use abi_stable::StableAbi;
21use arrow::{
22    array::{make_array, ArrayRef},
23    datatypes::{Schema, SchemaRef},
24    ffi::{from_ffi, FFI_ArrowArray, FFI_ArrowSchema},
25};
26use log::error;
27
28/// This is a wrapper struct around FFI_ArrowSchema simply to indicate
29/// to the StableAbi macros that the underlying struct is FFI safe.
30#[repr(C)]
31#[derive(Debug, StableAbi)]
32pub struct WrappedSchema(#[sabi(unsafe_opaque_field)] pub FFI_ArrowSchema);
33
34impl From<SchemaRef> for WrappedSchema {
35    fn from(value: SchemaRef) -> Self {
36        let ffi_schema = match FFI_ArrowSchema::try_from(value.as_ref()) {
37            Ok(s) => s,
38            Err(e) => {
39                error!("Unable to convert DataFusion Schema to FFI_ArrowSchema in FFI_PlanProperties. {}", e);
40                FFI_ArrowSchema::empty()
41            }
42        };
43
44        WrappedSchema(ffi_schema)
45    }
46}
47
48impl From<WrappedSchema> for SchemaRef {
49    fn from(value: WrappedSchema) -> Self {
50        let schema = match Schema::try_from(&value.0) {
51            Ok(s) => s,
52            Err(e) => {
53                error!("Unable to convert from FFI_ArrowSchema to DataFusion Schema in FFI_PlanProperties. {}", e);
54                Schema::empty()
55            }
56        };
57        Arc::new(schema)
58    }
59}
60
61/// This is a wrapper struct for FFI_ArrowArray to indicate to StableAbi
62/// that the struct is FFI Safe. For convenience, we also include the
63/// schema needed to create a record batch from the array.
64#[repr(C)]
65#[derive(Debug, StableAbi)]
66pub struct WrappedArray {
67    #[sabi(unsafe_opaque_field)]
68    pub array: FFI_ArrowArray,
69
70    pub schema: WrappedSchema,
71}
72
73impl TryFrom<WrappedArray> for ArrayRef {
74    type Error = arrow::error::ArrowError;
75
76    fn try_from(value: WrappedArray) -> Result<Self, Self::Error> {
77        let data = unsafe { from_ffi(value.array, &value.schema.0)? };
78
79        Ok(make_array(data))
80    }
81}