datafusion_ffi/expr/
expr_properties.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 arrow_schema::SortOptions;
20use datafusion_common::DataFusionError;
21use datafusion_expr::sort_properties::{ExprProperties, SortProperties};
22
23use crate::expr::interval::FFI_Interval;
24
25/// A stable struct for sharing [`ExprProperties`] across FFI boundaries.
26/// See [`ExprProperties`] for the meaning of each field.
27#[repr(C)]
28#[derive(Debug, StableAbi)]
29pub struct FFI_ExprProperties {
30    sort_properties: FFI_SortProperties,
31    range: FFI_Interval,
32    preserves_lex_ordering: bool,
33}
34
35impl TryFrom<&ExprProperties> for FFI_ExprProperties {
36    type Error = DataFusionError;
37    fn try_from(value: &ExprProperties) -> Result<Self, Self::Error> {
38        let sort_properties = (&value.sort_properties).into();
39        let range = value.range.clone().try_into()?;
40
41        Ok(FFI_ExprProperties {
42            sort_properties,
43            range,
44            preserves_lex_ordering: value.preserves_lex_ordering,
45        })
46    }
47}
48
49impl TryFrom<FFI_ExprProperties> for ExprProperties {
50    type Error = DataFusionError;
51    fn try_from(value: FFI_ExprProperties) -> Result<Self, Self::Error> {
52        let sort_properties = (&value.sort_properties).into();
53        let range = value.range.try_into()?;
54        Ok(ExprProperties {
55            sort_properties,
56            range,
57            preserves_lex_ordering: value.preserves_lex_ordering,
58        })
59    }
60}
61
62#[repr(C)]
63#[derive(Debug, StableAbi)]
64pub enum FFI_SortProperties {
65    Ordered(FFI_SortOptions),
66    Unordered,
67    Singleton,
68}
69
70impl From<&SortProperties> for FFI_SortProperties {
71    fn from(value: &SortProperties) -> Self {
72        match value {
73            SortProperties::Unordered => FFI_SortProperties::Unordered,
74            SortProperties::Singleton => FFI_SortProperties::Singleton,
75            SortProperties::Ordered(o) => FFI_SortProperties::Ordered(o.into()),
76        }
77    }
78}
79
80impl From<&FFI_SortProperties> for SortProperties {
81    fn from(value: &FFI_SortProperties) -> Self {
82        match value {
83            FFI_SortProperties::Unordered => SortProperties::Unordered,
84            FFI_SortProperties::Singleton => SortProperties::Singleton,
85            FFI_SortProperties::Ordered(o) => SortProperties::Ordered(o.into()),
86        }
87    }
88}
89
90#[repr(C)]
91#[derive(Debug, StableAbi)]
92pub struct FFI_SortOptions {
93    pub descending: bool,
94    pub nulls_first: bool,
95}
96
97impl From<&SortOptions> for FFI_SortOptions {
98    fn from(value: &SortOptions) -> Self {
99        Self {
100            descending: value.descending,
101            nulls_first: value.nulls_first,
102        }
103    }
104}
105
106impl From<&FFI_SortOptions> for SortOptions {
107    fn from(value: &FFI_SortOptions) -> Self {
108        Self {
109            descending: value.descending,
110            nulls_first: value.nulls_first,
111        }
112    }
113}