datafusion_ffi/
table_source.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 abi_stable::StableAbi;
19use datafusion::{datasource::TableType, logical_expr::TableProviderFilterPushDown};
20
21/// FFI safe version of [`TableProviderFilterPushDown`].
22#[repr(C)]
23#[derive(StableAbi)]
24#[allow(non_camel_case_types)]
25pub enum FFI_TableProviderFilterPushDown {
26    Unsupported,
27    Inexact,
28    Exact,
29}
30
31impl From<&FFI_TableProviderFilterPushDown> for TableProviderFilterPushDown {
32    fn from(value: &FFI_TableProviderFilterPushDown) -> Self {
33        match value {
34            FFI_TableProviderFilterPushDown::Unsupported => {
35                TableProviderFilterPushDown::Unsupported
36            }
37            FFI_TableProviderFilterPushDown::Inexact => {
38                TableProviderFilterPushDown::Inexact
39            }
40            FFI_TableProviderFilterPushDown::Exact => TableProviderFilterPushDown::Exact,
41        }
42    }
43}
44
45impl From<&TableProviderFilterPushDown> for FFI_TableProviderFilterPushDown {
46    fn from(value: &TableProviderFilterPushDown) -> Self {
47        match value {
48            TableProviderFilterPushDown::Unsupported => {
49                FFI_TableProviderFilterPushDown::Unsupported
50            }
51            TableProviderFilterPushDown::Inexact => {
52                FFI_TableProviderFilterPushDown::Inexact
53            }
54            TableProviderFilterPushDown::Exact => FFI_TableProviderFilterPushDown::Exact,
55        }
56    }
57}
58
59/// FFI safe version of [`TableType`].
60#[repr(C)]
61#[allow(non_camel_case_types)]
62#[derive(Debug, Clone, Copy, PartialEq, Eq, StableAbi)]
63pub enum FFI_TableType {
64    Base,
65    View,
66    Temporary,
67}
68
69impl From<FFI_TableType> for TableType {
70    fn from(value: FFI_TableType) -> Self {
71        match value {
72            FFI_TableType::Base => TableType::Base,
73            FFI_TableType::View => TableType::View,
74            FFI_TableType::Temporary => TableType::Temporary,
75        }
76    }
77}
78
79impl From<TableType> for FFI_TableType {
80    fn from(value: TableType) -> Self {
81        match value {
82            TableType::Base => FFI_TableType::Base,
83            TableType::View => FFI_TableType::View,
84            TableType::Temporary => FFI_TableType::Temporary,
85        }
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92    use datafusion::error::Result;
93
94    fn round_trip_filter_pushdown(pushdown: TableProviderFilterPushDown) -> Result<()> {
95        let ffi_pushdown: FFI_TableProviderFilterPushDown = (&pushdown).into();
96        let round_trip: TableProviderFilterPushDown = (&ffi_pushdown).into();
97
98        assert_eq!(pushdown, round_trip);
99        Ok(())
100    }
101
102    #[test]
103    fn round_trip_all_filter_pushdowns() -> Result<()> {
104        round_trip_filter_pushdown(TableProviderFilterPushDown::Exact)?;
105        round_trip_filter_pushdown(TableProviderFilterPushDown::Inexact)?;
106        round_trip_filter_pushdown(TableProviderFilterPushDown::Unsupported)?;
107
108        Ok(())
109    }
110
111    fn round_trip_table_type(table_type: TableType) -> Result<()> {
112        let ffi_type: FFI_TableType = table_type.into();
113        let round_trip_type: TableType = ffi_type.into();
114
115        assert_eq!(table_type, round_trip_type);
116        Ok(())
117    }
118
119    #[test]
120    fn test_round_all_trip_table_type() -> Result<()> {
121        round_trip_table_type(TableType::Base)?;
122        round_trip_table_type(TableType::Temporary)?;
123        round_trip_table_type(TableType::View)?;
124
125        Ok(())
126    }
127}