18
18
//! Signature module contains foundational types that are used to represent signatures, types,
19
19
//! and return types of functions in DataFusion.
20
20
21
- use crate :: type_coercion:: aggregates:: { NUMERICS , STRINGS } ;
21
+ use crate :: type_coercion:: aggregates:: NUMERICS ;
22
22
use arrow:: datatypes:: DataType ;
23
23
use datafusion_common:: types:: { LogicalTypeRef , NativeType } ;
24
24
use itertools:: Itertools ;
@@ -113,6 +113,15 @@ pub enum TypeSignature {
113
113
/// arguments like `vec![DataType::Int32]` or `vec![DataType::Float32]`
114
114
/// since i32 and f32 can be casted to f64
115
115
Coercible ( Vec < LogicalTypeRef > ) ,
116
+ /// The arguments will be coerced to a single type based on the comparison rules.
117
+ /// For example, i32 and i64 has coerced type Int64.
118
+ ///
119
+ /// Note:
120
+ /// - If compares with numeric and string, numeric is preferred for numeric string cases. For example, nullif('2', 1) has coerced types Int64.
121
+ /// - If the result is Null, it will be coerced to String (Utf8View).
122
+ ///
123
+ /// See `comparison_coercion_numeric` for more details.
124
+ Comparable ( usize ) ,
116
125
/// Fixed number of arguments of arbitrary types, number should be larger than 0
117
126
Any ( usize ) ,
118
127
/// Matches exactly one of a list of [`TypeSignature`]s. Coercion is attempted to match
@@ -138,6 +147,13 @@ pub enum TypeSignature {
138
147
NullAry ,
139
148
}
140
149
150
+ impl TypeSignature {
151
+ #[ inline]
152
+ pub fn is_one_of ( & self ) -> bool {
153
+ matches ! ( self , TypeSignature :: OneOf ( _) )
154
+ }
155
+ }
156
+
141
157
#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Hash ) ]
142
158
pub enum ArrayFunctionSignature {
143
159
/// Specialized Signature for ArrayAppend and similar functions
@@ -210,6 +226,9 @@ impl TypeSignature {
210
226
TypeSignature :: Numeric ( num) => {
211
227
vec ! [ format!( "Numeric({num})" ) ]
212
228
}
229
+ TypeSignature :: Comparable ( num) => {
230
+ vec ! [ format!( "Comparable({num})" ) ]
231
+ }
213
232
TypeSignature :: Coercible ( types) => {
214
233
vec ! [ Self :: join_types( types, ", " ) ]
215
234
}
@@ -284,13 +303,13 @@ impl TypeSignature {
284
303
. cloned ( )
285
304
. map ( |numeric_type| vec ! [ numeric_type; * arg_count] )
286
305
. collect ( ) ,
287
- TypeSignature :: String ( arg_count) => STRINGS
288
- . iter ( )
289
- . cloned ( )
290
- . map ( |string_type| vec ! [ string_type; * arg_count] )
291
- . collect ( ) ,
306
+ TypeSignature :: String ( arg_count) => get_data_types ( & NativeType :: String )
307
+ . into_iter ( )
308
+ . map ( |dt| vec ! [ dt; * arg_count] )
309
+ . collect :: < Vec < _ > > ( ) ,
292
310
// TODO: Implement for other types
293
311
TypeSignature :: Any ( _)
312
+ | TypeSignature :: Comparable ( _)
294
313
| TypeSignature :: NullAry
295
314
| TypeSignature :: VariadicAny
296
315
| TypeSignature :: ArraySignature ( _)
@@ -412,6 +431,14 @@ impl Signature {
412
431
}
413
432
}
414
433
434
+ /// Used for function that expects comparable data types, it will try to coerced all the types into single final one.
435
+ pub fn comparable ( arg_count : usize , volatility : Volatility ) -> Self {
436
+ Self {
437
+ type_signature : TypeSignature :: Comparable ( arg_count) ,
438
+ volatility,
439
+ }
440
+ }
441
+
415
442
pub fn nullary ( volatility : Volatility ) -> Self {
416
443
Signature {
417
444
type_signature : TypeSignature :: NullAry ,
0 commit comments