common_query/
signature.rs1pub use datafusion_expr::Volatility;
19use datafusion_expr::{Signature as DfSignature, TypeSignature as DfTypeSignature};
20use datatypes::arrow::datatypes::DataType as ArrowDataType;
21use datatypes::data_type::DataType;
22use datatypes::prelude::ConcreteDataType;
23
24#[derive(Debug, Clone, PartialEq)]
26pub enum TypeSignature {
27 Variadic(Vec<ConcreteDataType>),
30 VariadicAny,
32 Uniform(usize, Vec<ConcreteDataType>),
36 Exact(Vec<ConcreteDataType>),
38 Any(usize),
40 OneOf(Vec<TypeSignature>),
42 NullAry,
46}
47
48#[derive(Debug, Clone, PartialEq)]
50pub struct Signature {
51 pub type_signature: TypeSignature,
53 pub volatility: Volatility,
55}
56
57#[inline]
58fn concrete_types_to_arrow_types(ts: Vec<ConcreteDataType>) -> Vec<ArrowDataType> {
59 ts.iter().map(ConcreteDataType::as_arrow_type).collect()
60}
61
62impl Signature {
63 pub fn new(type_signature: TypeSignature, volatility: Volatility) -> Self {
65 Signature {
66 type_signature,
67 volatility,
68 }
69 }
70
71 pub fn variadic(common_types: Vec<ConcreteDataType>, volatility: Volatility) -> Self {
73 Self {
74 type_signature: TypeSignature::Variadic(common_types),
75 volatility,
76 }
77 }
78
79 pub fn variadic_any(volatility: Volatility) -> Self {
81 Self {
82 type_signature: TypeSignature::VariadicAny,
83 volatility,
84 }
85 }
86
87 pub fn uniform(
89 arg_count: usize,
90 valid_types: Vec<ConcreteDataType>,
91 volatility: Volatility,
92 ) -> Self {
93 Self {
94 type_signature: TypeSignature::Uniform(arg_count, valid_types),
95 volatility,
96 }
97 }
98 pub fn exact(exact_types: Vec<ConcreteDataType>, volatility: Volatility) -> Self {
100 Signature {
101 type_signature: TypeSignature::Exact(exact_types),
102 volatility,
103 }
104 }
105 pub fn any(arg_count: usize, volatility: Volatility) -> Self {
107 Signature {
108 type_signature: TypeSignature::Any(arg_count),
109 volatility,
110 }
111 }
112 pub fn one_of(type_signatures: Vec<TypeSignature>, volatility: Volatility) -> Self {
114 Signature {
115 type_signature: TypeSignature::OneOf(type_signatures),
116 volatility,
117 }
118 }
119
120 pub fn nullary(volatility: Volatility) -> Self {
121 Signature {
122 type_signature: TypeSignature::NullAry,
123 volatility,
124 }
125 }
126}
127
128impl From<TypeSignature> for DfTypeSignature {
130 fn from(type_signature: TypeSignature) -> DfTypeSignature {
131 match type_signature {
132 TypeSignature::Variadic(types) => {
133 DfTypeSignature::Variadic(concrete_types_to_arrow_types(types))
134 }
135 TypeSignature::Uniform(n, types) => {
136 if n == 0 {
137 return DfTypeSignature::Nullary;
138 }
139 DfTypeSignature::Uniform(n, concrete_types_to_arrow_types(types))
140 }
141 TypeSignature::Exact(types) => {
142 DfTypeSignature::Exact(concrete_types_to_arrow_types(types))
143 }
144 TypeSignature::Any(n) => {
145 if n == 0 {
146 return DfTypeSignature::Nullary;
147 }
148 DfTypeSignature::Any(n)
149 }
150 TypeSignature::OneOf(ts) => {
151 DfTypeSignature::OneOf(ts.into_iter().map(Into::into).collect())
152 }
153 TypeSignature::VariadicAny => DfTypeSignature::VariadicAny,
154 TypeSignature::NullAry => DfTypeSignature::Nullary,
155 }
156 }
157}
158
159impl From<&DfTypeSignature> for TypeSignature {
160 fn from(type_signature: &DfTypeSignature) -> TypeSignature {
161 match type_signature {
162 DfTypeSignature::Variadic(types) => TypeSignature::Variadic(
163 types
164 .iter()
165 .map(ConcreteDataType::from_arrow_type)
166 .collect(),
167 ),
168 DfTypeSignature::Uniform(n, types) => {
169 if *n == 0 {
170 return TypeSignature::NullAry;
171 }
172 TypeSignature::Uniform(
173 *n,
174 types
175 .iter()
176 .map(ConcreteDataType::from_arrow_type)
177 .collect(),
178 )
179 }
180 DfTypeSignature::Exact(types) => TypeSignature::Exact(
181 types
182 .iter()
183 .map(ConcreteDataType::from_arrow_type)
184 .collect(),
185 ),
186 DfTypeSignature::Any(n) => {
187 if *n == 0 {
188 return TypeSignature::NullAry;
189 }
190 TypeSignature::Any(*n)
191 }
192 DfTypeSignature::OneOf(ts) => TypeSignature::OneOf(ts.iter().map(Into::into).collect()),
193 DfTypeSignature::VariadicAny => TypeSignature::VariadicAny,
194 DfTypeSignature::Nullary => TypeSignature::NullAry,
195 _ => TypeSignature::VariadicAny,
198 }
199 }
200}
201
202impl From<Signature> for DfSignature {
203 fn from(sig: Signature) -> DfSignature {
204 DfSignature::new(sig.type_signature.into(), sig.volatility)
205 }
206}
207
208#[cfg(test)]
209mod tests {
210 use datatypes::arrow::datatypes::DataType;
211
212 use super::*;
213
214 #[test]
215 fn test_into_df_signature() {
216 let types = vec![
217 ConcreteDataType::int8_datatype(),
218 ConcreteDataType::float32_datatype(),
219 ConcreteDataType::float64_datatype(),
220 ];
221 let sig = Signature::exact(types.clone(), Volatility::Immutable);
222
223 assert_eq!(Volatility::Immutable, sig.volatility);
224 assert!(matches!(&sig.type_signature, TypeSignature::Exact(x) if x.clone() == types));
225
226 let df_sig = DfSignature::from(sig);
227 assert_eq!(Volatility::Immutable, df_sig.volatility);
228 let types = vec![DataType::Int8, DataType::Float32, DataType::Float64];
229 assert!(matches!(df_sig.type_signature, DfTypeSignature::Exact(x) if x == types));
230 }
231}