19
19
//! and return types of functions in DataFusion.
20
20
21
21
use std:: fmt:: Display ;
22
- use std:: num:: NonZeroUsize ;
23
22
24
23
use crate :: type_coercion:: aggregates:: NUMERICS ;
25
24
use arrow:: datatypes:: { DataType , IntervalUnit , TimeUnit } ;
26
25
use datafusion_common:: types:: { LogicalTypeRef , NativeType } ;
26
+ use datafusion_common:: utils:: ListCoercion ;
27
27
use itertools:: Itertools ;
28
28
29
29
/// Constant that is used as a placeholder for any valid timezone.
@@ -227,25 +227,13 @@ impl Display for TypeSignatureClass {
227
227
228
228
#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Hash ) ]
229
229
pub enum ArrayFunctionSignature {
230
- /// Specialized Signature for ArrayAppend and similar functions
231
- /// The first argument should be List/LargeList/FixedSizedList, and the second argument should be non-list or list.
232
- /// The second argument's list dimension should be one dimension less than the first argument's list dimension.
233
- /// List dimension of the List/LargeList is equivalent to the number of List.
234
- /// List dimension of the non-list is 0.
235
- ArrayAndElement ,
236
- /// Specialized Signature for ArrayPrepend and similar functions
237
- /// The first argument should be non-list or list, and the second argument should be List/LargeList.
238
- /// The first argument's list dimension should be one dimension less than the second argument's list dimension.
239
- ElementAndArray ,
240
- /// Specialized Signature for Array functions of the form (List/LargeList, Index+)
241
- /// The first argument should be List/LargeList/FixedSizedList, and the next n arguments should be Int64.
242
- ArrayAndIndexes ( NonZeroUsize ) ,
243
- /// Specialized Signature for Array functions of the form (List/LargeList, Element, Optional Index)
244
- ArrayAndElementAndOptionalIndex ,
245
- /// Specialized Signature for ArrayEmpty and similar functions
246
- /// The function takes a single argument that must be a List/LargeList/FixedSizeList
247
- /// or something that can be coerced to one of those types.
248
- Array ,
230
+ /// A function takes at least one List/LargeList/FixedSizeList argument.
231
+ Array {
232
+ /// A full list of the arguments accepted by this function.
233
+ arguments : Vec < ArrayFunctionArgument > ,
234
+ /// Additional information about how array arguments should be coerced.
235
+ array_coercion : Option < ListCoercion > ,
236
+ } ,
249
237
/// A function takes a single argument that must be a List/LargeList/FixedSizeList
250
238
/// which gets coerced to List, with element type recursively coerced to List too if it is list-like.
251
239
RecursiveArray ,
@@ -257,25 +245,15 @@ pub enum ArrayFunctionSignature {
257
245
impl Display for ArrayFunctionSignature {
258
246
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
259
247
match self {
260
- ArrayFunctionSignature :: ArrayAndElement => {
261
- write ! ( f, "array, element" )
262
- }
263
- ArrayFunctionSignature :: ArrayAndElementAndOptionalIndex => {
264
- write ! ( f, "array, element, [index]" )
265
- }
266
- ArrayFunctionSignature :: ElementAndArray => {
267
- write ! ( f, "element, array" )
268
- }
269
- ArrayFunctionSignature :: ArrayAndIndexes ( count) => {
270
- write ! ( f, "array" ) ?;
271
- for _ in 0 ..count. get ( ) {
272
- write ! ( f, ", index" ) ?;
248
+ ArrayFunctionSignature :: Array { arguments, .. } => {
249
+ for ( idx, argument) in arguments. iter ( ) . enumerate ( ) {
250
+ write ! ( f, "{argument}" ) ?;
251
+ if idx != arguments. len ( ) - 1 {
252
+ write ! ( f, ", " ) ?;
253
+ }
273
254
}
274
255
Ok ( ( ) )
275
256
}
276
- ArrayFunctionSignature :: Array => {
277
- write ! ( f, "array" )
278
- }
279
257
ArrayFunctionSignature :: RecursiveArray => {
280
258
write ! ( f, "recursive_array" )
281
259
}
@@ -286,6 +264,34 @@ impl Display for ArrayFunctionSignature {
286
264
}
287
265
}
288
266
267
+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Hash ) ]
268
+ pub enum ArrayFunctionArgument {
269
+ /// A non-list or list argument. The list dimensions should be one less than the Array's list
270
+ /// dimensions.
271
+ Element ,
272
+ /// An Int64 index argument.
273
+ Index ,
274
+ /// An argument of type List/LargeList/FixedSizeList. All Array arguments must be coercible
275
+ /// to the same type.
276
+ Array ,
277
+ }
278
+
279
+ impl Display for ArrayFunctionArgument {
280
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
281
+ match self {
282
+ ArrayFunctionArgument :: Element => {
283
+ write ! ( f, "element" )
284
+ }
285
+ ArrayFunctionArgument :: Index => {
286
+ write ! ( f, "index" )
287
+ }
288
+ ArrayFunctionArgument :: Array => {
289
+ write ! ( f, "array" )
290
+ }
291
+ }
292
+ }
293
+ }
294
+
289
295
impl TypeSignature {
290
296
pub fn to_string_repr ( & self ) -> Vec < String > {
291
297
match self {
@@ -580,46 +586,65 @@ impl Signature {
580
586
pub fn array_and_element ( volatility : Volatility ) -> Self {
581
587
Signature {
582
588
type_signature : TypeSignature :: ArraySignature (
583
- ArrayFunctionSignature :: ArrayAndElement ,
589
+ ArrayFunctionSignature :: Array {
590
+ arguments : vec ! [
591
+ ArrayFunctionArgument :: Array ,
592
+ ArrayFunctionArgument :: Element ,
593
+ ] ,
594
+ array_coercion : Some ( ListCoercion :: FixedSizedListToList ) ,
595
+ } ,
584
596
) ,
585
597
volatility,
586
598
}
587
599
}
588
600
/// Specialized Signature for Array functions with an optional index
589
601
pub fn array_and_element_and_optional_index ( volatility : Volatility ) -> Self {
590
602
Signature {
591
- type_signature : TypeSignature :: ArraySignature (
592
- ArrayFunctionSignature :: ArrayAndElementAndOptionalIndex ,
593
- ) ,
594
- volatility,
595
- }
596
- }
597
- /// Specialized Signature for ArrayPrepend and similar functions
598
- pub fn element_and_array ( volatility : Volatility ) -> Self {
599
- Signature {
600
- type_signature : TypeSignature :: ArraySignature (
601
- ArrayFunctionSignature :: ElementAndArray ,
602
- ) ,
603
+ type_signature : TypeSignature :: OneOf ( vec ! [
604
+ TypeSignature :: ArraySignature ( ArrayFunctionSignature :: Array {
605
+ arguments: vec![
606
+ ArrayFunctionArgument :: Array ,
607
+ ArrayFunctionArgument :: Element ,
608
+ ] ,
609
+ array_coercion: None ,
610
+ } ) ,
611
+ TypeSignature :: ArraySignature ( ArrayFunctionSignature :: Array {
612
+ arguments: vec![
613
+ ArrayFunctionArgument :: Array ,
614
+ ArrayFunctionArgument :: Element ,
615
+ ArrayFunctionArgument :: Index ,
616
+ ] ,
617
+ array_coercion: None ,
618
+ } ) ,
619
+ ] ) ,
603
620
volatility,
604
621
}
605
622
}
623
+
606
624
/// Specialized Signature for ArrayElement and similar functions
607
625
pub fn array_and_index ( volatility : Volatility ) -> Self {
608
- Self :: array_and_indexes ( volatility, NonZeroUsize :: new ( 1 ) . expect ( "1 is non-zero" ) )
609
- }
610
- /// Specialized Signature for ArraySlice and similar functions
611
- pub fn array_and_indexes ( volatility : Volatility , count : NonZeroUsize ) -> Self {
612
626
Signature {
613
627
type_signature : TypeSignature :: ArraySignature (
614
- ArrayFunctionSignature :: ArrayAndIndexes ( count) ,
628
+ ArrayFunctionSignature :: Array {
629
+ arguments : vec ! [
630
+ ArrayFunctionArgument :: Array ,
631
+ ArrayFunctionArgument :: Index ,
632
+ ] ,
633
+ array_coercion : None ,
634
+ } ,
615
635
) ,
616
636
volatility,
617
637
}
618
638
}
619
639
/// Specialized Signature for ArrayEmpty and similar functions
620
640
pub fn array ( volatility : Volatility ) -> Self {
621
641
Signature {
622
- type_signature : TypeSignature :: ArraySignature ( ArrayFunctionSignature :: Array ) ,
642
+ type_signature : TypeSignature :: ArraySignature (
643
+ ArrayFunctionSignature :: Array {
644
+ arguments : vec ! [ ArrayFunctionArgument :: Array ] ,
645
+ array_coercion : None ,
646
+ } ,
647
+ ) ,
623
648
volatility,
624
649
}
625
650
}
0 commit comments