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<Signature> for DfSignature {
160 fn from(sig: Signature) -> DfSignature {
161 DfSignature::new(sig.type_signature.into(), sig.volatility)
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use datatypes::arrow::datatypes::DataType;
168
169 use super::*;
170
171 #[test]
172 fn test_into_df_signature() {
173 let types = vec![
174 ConcreteDataType::int8_datatype(),
175 ConcreteDataType::float32_datatype(),
176 ConcreteDataType::float64_datatype(),
177 ];
178 let sig = Signature::exact(types.clone(), Volatility::Immutable);
179
180 assert_eq!(Volatility::Immutable, sig.volatility);
181 assert!(matches!(&sig.type_signature, TypeSignature::Exact(x) if x.clone() == types));
182
183 let df_sig = DfSignature::from(sig);
184 assert_eq!(Volatility::Immutable, df_sig.volatility);
185 let types = vec![DataType::Int8, DataType::Float32, DataType::Float64];
186 assert!(matches!(df_sig.type_signature, DfTypeSignature::Exact(x) if x == types));
187 }
188}