1818//! Signature module contains foundational types that are used to represent signatures, types,
1919//! and return types of functions in DataFusion.
2020
21- use crate :: type_coercion:: aggregates:: { NUMERICS , STRINGS } ;
21+ use crate :: type_coercion:: aggregates:: NUMERICS ;
2222use arrow:: datatypes:: DataType ;
2323use datafusion_common:: types:: { LogicalTypeRef , NativeType } ;
2424use itertools:: Itertools ;
@@ -113,6 +113,15 @@ pub enum TypeSignature {
113113 /// arguments like `vec![DataType::Int32]` or `vec![DataType::Float32]`
114114 /// since i32 and f32 can be casted to f64
115115 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 ) ,
116125 /// Fixed number of arguments of arbitrary types, number should be larger than 0
117126 Any ( usize ) ,
118127 /// Matches exactly one of a list of [`TypeSignature`]s. Coercion is attempted to match
@@ -138,6 +147,13 @@ pub enum TypeSignature {
138147 NullAry ,
139148}
140149
150+ impl TypeSignature {
151+ #[ inline]
152+ pub fn is_one_of ( & self ) -> bool {
153+ matches ! ( self , TypeSignature :: OneOf ( _) )
154+ }
155+ }
156+
141157#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Hash ) ]
142158pub enum ArrayFunctionSignature {
143159 /// Specialized Signature for ArrayAppend and similar functions
@@ -210,6 +226,9 @@ impl TypeSignature {
210226 TypeSignature :: Numeric ( num) => {
211227 vec ! [ format!( "Numeric({num})" ) ]
212228 }
229+ TypeSignature :: Comparable ( num) => {
230+ vec ! [ format!( "Comparable({num})" ) ]
231+ }
213232 TypeSignature :: Coercible ( types) => {
214233 vec ! [ Self :: join_types( types, ", " ) ]
215234 }
@@ -284,13 +303,13 @@ impl TypeSignature {
284303 . cloned ( )
285304 . map ( |numeric_type| vec ! [ numeric_type; * arg_count] )
286305 . 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 < _ > > ( ) ,
292310 // TODO: Implement for other types
293311 TypeSignature :: Any ( _)
312+ | TypeSignature :: Comparable ( _)
294313 | TypeSignature :: NullAry
295314 | TypeSignature :: VariadicAny
296315 | TypeSignature :: ArraySignature ( _)
@@ -412,6 +431,14 @@ impl Signature {
412431 }
413432 }
414433
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+
415442 pub fn nullary ( volatility : Volatility ) -> Self {
416443 Signature {
417444 type_signature : TypeSignature :: NullAry ,
0 commit comments