datafusion_ffi/expr/
distribution.rs1use abi_stable::StableAbi;
19use datafusion_common::DataFusionError;
20use datafusion_expr::statistics::{
21 BernoulliDistribution, Distribution, ExponentialDistribution, GaussianDistribution,
22 GenericDistribution, UniformDistribution,
23};
24
25use crate::arrow_wrappers::WrappedArray;
26use crate::expr::interval::FFI_Interval;
27
28#[repr(C)]
31#[derive(Debug, StableAbi)]
32#[expect(clippy::large_enum_variant)]
33pub enum FFI_Distribution {
34 Uniform(FFI_UniformDistribution),
35 Exponential(FFI_ExponentialDistribution),
36 Gaussian(FFI_GaussianDistribution),
37 Bernoulli(FFI_BernoulliDistribution),
38 Generic(FFI_GenericDistribution),
39}
40
41impl TryFrom<&Distribution> for FFI_Distribution {
42 type Error = DataFusionError;
43 fn try_from(value: &Distribution) -> Result<Self, Self::Error> {
44 match value {
45 Distribution::Uniform(d) => Ok(FFI_Distribution::Uniform(d.try_into()?)),
46 Distribution::Exponential(d) => {
47 Ok(FFI_Distribution::Exponential(d.try_into()?))
48 }
49 Distribution::Gaussian(d) => Ok(FFI_Distribution::Gaussian(d.try_into()?)),
50 Distribution::Bernoulli(d) => Ok(FFI_Distribution::Bernoulli(d.try_into()?)),
51 Distribution::Generic(d) => Ok(FFI_Distribution::Generic(d.try_into()?)),
52 }
53 }
54}
55
56impl TryFrom<FFI_Distribution> for Distribution {
57 type Error = DataFusionError;
58 fn try_from(value: FFI_Distribution) -> Result<Self, Self::Error> {
59 match value {
60 FFI_Distribution::Uniform(d) => d.try_into(),
61 FFI_Distribution::Exponential(d) => d.try_into(),
62 FFI_Distribution::Gaussian(d) => d.try_into(),
63 FFI_Distribution::Bernoulli(d) => d.try_into(),
64 FFI_Distribution::Generic(d) => d.try_into(),
65 }
66 }
67}
68
69#[repr(C)]
70#[derive(Debug, StableAbi)]
71pub struct FFI_UniformDistribution {
72 interval: FFI_Interval,
73}
74
75#[repr(C)]
76#[derive(Debug, StableAbi)]
77pub struct FFI_ExponentialDistribution {
78 rate: WrappedArray,
79 offset: WrappedArray,
80 positive_tail: bool,
81}
82
83#[repr(C)]
84#[derive(Debug, StableAbi)]
85pub struct FFI_GaussianDistribution {
86 mean: WrappedArray,
87 variance: WrappedArray,
88}
89
90#[repr(C)]
91#[derive(Debug, StableAbi)]
92pub struct FFI_BernoulliDistribution {
93 p: WrappedArray,
94}
95
96#[repr(C)]
97#[derive(Debug, StableAbi)]
98pub struct FFI_GenericDistribution {
99 mean: WrappedArray,
100 median: WrappedArray,
101 variance: WrappedArray,
102 range: FFI_Interval,
103}
104
105impl TryFrom<&UniformDistribution> for FFI_UniformDistribution {
106 type Error = DataFusionError;
107 fn try_from(value: &UniformDistribution) -> Result<Self, Self::Error> {
108 Ok(Self {
109 interval: value.range().try_into()?,
110 })
111 }
112}
113
114impl TryFrom<&ExponentialDistribution> for FFI_ExponentialDistribution {
115 type Error = DataFusionError;
116 fn try_from(value: &ExponentialDistribution) -> Result<Self, Self::Error> {
117 let rate = value.rate().try_into()?;
118 let offset = value.offset().try_into()?;
119
120 Ok(Self {
121 rate,
122 offset,
123 positive_tail: value.positive_tail(),
124 })
125 }
126}
127
128impl TryFrom<&GaussianDistribution> for FFI_GaussianDistribution {
129 type Error = DataFusionError;
130 fn try_from(value: &GaussianDistribution) -> Result<Self, Self::Error> {
131 let mean = value.mean().try_into()?;
132 let variance = value.variance().try_into()?;
133
134 Ok(Self { mean, variance })
135 }
136}
137
138impl TryFrom<&BernoulliDistribution> for FFI_BernoulliDistribution {
139 type Error = DataFusionError;
140 fn try_from(value: &BernoulliDistribution) -> Result<Self, Self::Error> {
141 let p = value.p_value().try_into()?;
142
143 Ok(Self { p })
144 }
145}
146
147impl TryFrom<&GenericDistribution> for FFI_GenericDistribution {
148 type Error = DataFusionError;
149 fn try_from(value: &GenericDistribution) -> Result<Self, Self::Error> {
150 let mean = value.mean().try_into()?;
151 let median = value.median().try_into()?;
152 let variance = value.variance().try_into()?;
153
154 Ok(Self {
155 mean,
156 median,
157 variance,
158 range: value.range().try_into()?,
159 })
160 }
161}
162
163impl TryFrom<FFI_UniformDistribution> for Distribution {
164 type Error = DataFusionError;
165 fn try_from(value: FFI_UniformDistribution) -> Result<Self, Self::Error> {
166 let interval = value.interval.try_into()?;
167 Distribution::new_uniform(interval)
168 }
169}
170
171impl TryFrom<FFI_ExponentialDistribution> for Distribution {
172 type Error = DataFusionError;
173 fn try_from(value: FFI_ExponentialDistribution) -> Result<Self, Self::Error> {
174 let rate = value.rate.try_into()?;
175 let offset = value.offset.try_into()?;
176
177 Distribution::new_exponential(rate, offset, value.positive_tail)
178 }
179}
180
181impl TryFrom<FFI_GaussianDistribution> for Distribution {
182 type Error = DataFusionError;
183 fn try_from(value: FFI_GaussianDistribution) -> Result<Self, Self::Error> {
184 let mean = value.mean.try_into()?;
185 let variance = value.variance.try_into()?;
186
187 Distribution::new_gaussian(mean, variance)
188 }
189}
190
191impl TryFrom<FFI_BernoulliDistribution> for Distribution {
192 type Error = DataFusionError;
193 fn try_from(value: FFI_BernoulliDistribution) -> Result<Self, Self::Error> {
194 let p = value.p.try_into()?;
195
196 Distribution::new_bernoulli(p)
197 }
198}
199
200impl TryFrom<FFI_GenericDistribution> for Distribution {
201 type Error = DataFusionError;
202 fn try_from(value: FFI_GenericDistribution) -> Result<Self, Self::Error> {
203 let mean = value.mean.try_into()?;
204 let median = value.median.try_into()?;
205 let variance = value.variance.try_into()?;
206 let range = value.range.try_into()?;
207
208 Distribution::new_generic(mean, median, variance, range)
209 }
210}