1use std::fmt::Display;
22use std::hash::Hash;
23
24use crate::type_coercion::aggregates::NUMERICS;
25use arrow::datatypes::{DataType, IntervalUnit, TimeUnit};
26use datafusion_common::internal_err;
27use datafusion_common::types::{LogicalType, LogicalTypeRef, NativeType};
28use datafusion_common::utils::ListCoercion;
29use indexmap::IndexSet;
30use itertools::Itertools;
31
32pub const TIMEZONE_WILDCARD: &str = "+TZ";
41
42pub const FIXED_SIZE_LIST_WILDCARD: i32 = i32::MIN;
46
47#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
49pub enum Volatility {
50 Immutable,
53 Stable,
61 Volatile,
68}
69
70#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
100pub enum TypeSignature {
101 Variadic(Vec<DataType>),
110 UserDefined,
118 VariadicAny,
120 Uniform(usize, Vec<DataType>),
127 Exact(Vec<DataType>),
131 Coercible(Vec<Coercion>),
138 Comparable(usize),
157 Any(usize),
161 OneOf(Vec<TypeSignature>),
171 ArraySignature(ArrayFunctionSignature),
173 Numeric(usize),
181 String(usize),
192 Nullary,
194}
195
196impl TypeSignature {
197 #[inline]
198 pub fn is_one_of(&self) -> bool {
199 matches!(self, TypeSignature::OneOf(_))
200 }
201}
202
203#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Hash)]
212pub enum TypeSignatureClass {
213 Timestamp,
214 Time,
215 Interval,
216 Duration,
217 Native(LogicalTypeRef),
218 Integer,
221}
222
223impl Display for TypeSignatureClass {
224 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
225 write!(f, "TypeSignatureClass::{self:?}")
226 }
227}
228
229impl TypeSignatureClass {
230 fn get_example_types(&self) -> Vec<DataType> {
235 match self {
236 TypeSignatureClass::Native(l) => get_data_types(l.native()),
237 TypeSignatureClass::Timestamp => {
238 vec![
239 DataType::Timestamp(TimeUnit::Nanosecond, None),
240 DataType::Timestamp(
241 TimeUnit::Nanosecond,
242 Some(TIMEZONE_WILDCARD.into()),
243 ),
244 ]
245 }
246 TypeSignatureClass::Time => {
247 vec![DataType::Time64(TimeUnit::Nanosecond)]
248 }
249 TypeSignatureClass::Interval => {
250 vec![DataType::Interval(IntervalUnit::DayTime)]
251 }
252 TypeSignatureClass::Duration => {
253 vec![DataType::Duration(TimeUnit::Nanosecond)]
254 }
255 TypeSignatureClass::Integer => {
256 vec![DataType::Int64]
257 }
258 }
259 }
260
261 pub fn matches_native_type(
263 self: &TypeSignatureClass,
264 logical_type: &NativeType,
265 ) -> bool {
266 if logical_type == &NativeType::Null {
267 return true;
268 }
269
270 match self {
271 TypeSignatureClass::Native(t) if t.native() == logical_type => true,
272 TypeSignatureClass::Timestamp if logical_type.is_timestamp() => true,
273 TypeSignatureClass::Time if logical_type.is_time() => true,
274 TypeSignatureClass::Interval if logical_type.is_interval() => true,
275 TypeSignatureClass::Duration if logical_type.is_duration() => true,
276 TypeSignatureClass::Integer if logical_type.is_integer() => true,
277 _ => false,
278 }
279 }
280
281 pub fn default_casted_type(
283 &self,
284 native_type: &NativeType,
285 origin_type: &DataType,
286 ) -> datafusion_common::Result<DataType> {
287 match self {
288 TypeSignatureClass::Native(logical_type) => {
289 logical_type.native().default_cast_for(origin_type)
290 }
291 TypeSignatureClass::Timestamp if native_type.is_timestamp() => {
293 Ok(origin_type.to_owned())
294 }
295 TypeSignatureClass::Time if native_type.is_time() => {
296 Ok(origin_type.to_owned())
297 }
298 TypeSignatureClass::Interval if native_type.is_interval() => {
299 Ok(origin_type.to_owned())
300 }
301 TypeSignatureClass::Duration if native_type.is_duration() => {
302 Ok(origin_type.to_owned())
303 }
304 TypeSignatureClass::Integer if native_type.is_integer() => {
305 Ok(origin_type.to_owned())
306 }
307 _ => internal_err!("May miss the matching logic in `matches_native_type`"),
308 }
309 }
310}
311
312#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
313pub enum ArrayFunctionSignature {
314 Array {
316 arguments: Vec<ArrayFunctionArgument>,
318 array_coercion: Option<ListCoercion>,
320 },
321 RecursiveArray,
324 MapArray,
327}
328
329impl Display for ArrayFunctionSignature {
330 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
331 match self {
332 ArrayFunctionSignature::Array { arguments, .. } => {
333 for (idx, argument) in arguments.iter().enumerate() {
334 write!(f, "{argument}")?;
335 if idx != arguments.len() - 1 {
336 write!(f, ", ")?;
337 }
338 }
339 Ok(())
340 }
341 ArrayFunctionSignature::RecursiveArray => {
342 write!(f, "recursive_array")
343 }
344 ArrayFunctionSignature::MapArray => {
345 write!(f, "map_array")
346 }
347 }
348 }
349}
350
351#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
352pub enum ArrayFunctionArgument {
353 Element,
356 Index,
358 Array,
361 String,
363}
364
365impl Display for ArrayFunctionArgument {
366 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
367 match self {
368 ArrayFunctionArgument::Element => {
369 write!(f, "element")
370 }
371 ArrayFunctionArgument::Index => {
372 write!(f, "index")
373 }
374 ArrayFunctionArgument::Array => {
375 write!(f, "array")
376 }
377 ArrayFunctionArgument::String => {
378 write!(f, "string")
379 }
380 }
381 }
382}
383
384impl TypeSignature {
385 pub fn to_string_repr(&self) -> Vec<String> {
386 match self {
387 TypeSignature::Nullary => {
388 vec!["NullAry()".to_string()]
389 }
390 TypeSignature::Variadic(types) => {
391 vec![format!("{}, ..", Self::join_types(types, "/"))]
392 }
393 TypeSignature::Uniform(arg_count, valid_types) => {
394 vec![
395 std::iter::repeat_n(Self::join_types(valid_types, "/"), *arg_count)
396 .collect::<Vec<String>>()
397 .join(", "),
398 ]
399 }
400 TypeSignature::String(num) => {
401 vec![format!("String({num})")]
402 }
403 TypeSignature::Numeric(num) => {
404 vec![format!("Numeric({num})")]
405 }
406 TypeSignature::Comparable(num) => {
407 vec![format!("Comparable({num})")]
408 }
409 TypeSignature::Coercible(coercions) => {
410 vec![Self::join_types(coercions, ", ")]
411 }
412 TypeSignature::Exact(types) => {
413 vec![Self::join_types(types, ", ")]
414 }
415 TypeSignature::Any(arg_count) => {
416 vec![std::iter::repeat_n("Any", *arg_count)
417 .collect::<Vec<&str>>()
418 .join(", ")]
419 }
420 TypeSignature::UserDefined => {
421 vec!["UserDefined".to_string()]
422 }
423 TypeSignature::VariadicAny => vec!["Any, .., Any".to_string()],
424 TypeSignature::OneOf(sigs) => {
425 sigs.iter().flat_map(|s| s.to_string_repr()).collect()
426 }
427 TypeSignature::ArraySignature(array_signature) => {
428 vec![array_signature.to_string()]
429 }
430 }
431 }
432
433 pub fn join_types<T: Display>(types: &[T], delimiter: &str) -> String {
435 types
436 .iter()
437 .map(|t| t.to_string())
438 .collect::<Vec<String>>()
439 .join(delimiter)
440 }
441
442 pub fn supports_zero_argument(&self) -> bool {
444 match &self {
445 TypeSignature::Exact(vec) => vec.is_empty(),
446 TypeSignature::Nullary => true,
447 TypeSignature::OneOf(types) => types
448 .iter()
449 .any(|type_sig| type_sig.supports_zero_argument()),
450 _ => false,
451 }
452 }
453
454 pub fn used_to_support_zero_arguments(&self) -> bool {
457 match &self {
458 TypeSignature::Any(num) => *num == 0,
459 _ => self.supports_zero_argument(),
460 }
461 }
462
463 #[deprecated(since = "46.0.0", note = "See get_example_types instead")]
464 pub fn get_possible_types(&self) -> Vec<Vec<DataType>> {
465 self.get_example_types()
466 }
467
468 pub fn get_example_types(&self) -> Vec<Vec<DataType>> {
475 match self {
476 TypeSignature::Exact(types) => vec![types.clone()],
477 TypeSignature::OneOf(types) => types
478 .iter()
479 .flat_map(|type_sig| type_sig.get_example_types())
480 .collect(),
481 TypeSignature::Uniform(arg_count, types) => types
482 .iter()
483 .cloned()
484 .map(|data_type| vec![data_type; *arg_count])
485 .collect(),
486 TypeSignature::Coercible(coercions) => coercions
487 .iter()
488 .map(|c| {
489 let mut all_types: IndexSet<DataType> =
490 c.desired_type().get_example_types().into_iter().collect();
491
492 if let Some(implicit_coercion) = c.implicit_coercion() {
493 let allowed_casts: Vec<DataType> = implicit_coercion
494 .allowed_source_types
495 .iter()
496 .flat_map(|t| t.get_example_types())
497 .collect();
498 all_types.extend(allowed_casts);
499 }
500
501 all_types.into_iter().collect::<Vec<_>>()
502 })
503 .multi_cartesian_product()
504 .collect(),
505 TypeSignature::Variadic(types) => types
506 .iter()
507 .cloned()
508 .map(|data_type| vec![data_type])
509 .collect(),
510 TypeSignature::Numeric(arg_count) => NUMERICS
511 .iter()
512 .cloned()
513 .map(|numeric_type| vec![numeric_type; *arg_count])
514 .collect(),
515 TypeSignature::String(arg_count) => get_data_types(&NativeType::String)
516 .into_iter()
517 .map(|dt| vec![dt; *arg_count])
518 .collect::<Vec<_>>(),
519 TypeSignature::Any(_)
521 | TypeSignature::Comparable(_)
522 | TypeSignature::Nullary
523 | TypeSignature::VariadicAny
524 | TypeSignature::ArraySignature(_)
525 | TypeSignature::UserDefined => vec![],
526 }
527 }
528}
529
530fn get_data_types(native_type: &NativeType) -> Vec<DataType> {
531 match native_type {
532 NativeType::Null => vec![DataType::Null],
533 NativeType::Boolean => vec![DataType::Boolean],
534 NativeType::Int8 => vec![DataType::Int8],
535 NativeType::Int16 => vec![DataType::Int16],
536 NativeType::Int32 => vec![DataType::Int32],
537 NativeType::Int64 => vec![DataType::Int64],
538 NativeType::UInt8 => vec![DataType::UInt8],
539 NativeType::UInt16 => vec![DataType::UInt16],
540 NativeType::UInt32 => vec![DataType::UInt32],
541 NativeType::UInt64 => vec![DataType::UInt64],
542 NativeType::Float16 => vec![DataType::Float16],
543 NativeType::Float32 => vec![DataType::Float32],
544 NativeType::Float64 => vec![DataType::Float64],
545 NativeType::Date => vec![DataType::Date32, DataType::Date64],
546 NativeType::Binary => vec![
547 DataType::Binary,
548 DataType::LargeBinary,
549 DataType::BinaryView,
550 ],
551 NativeType::String => {
552 vec![DataType::Utf8, DataType::LargeUtf8, DataType::Utf8View]
553 }
554 _ => vec![],
556 }
557}
558
559#[derive(Debug, Clone, Eq, PartialOrd)]
584pub enum Coercion {
585 Exact {
587 desired_type: TypeSignatureClass,
589 },
590
591 Implicit {
593 desired_type: TypeSignatureClass,
595 implicit_coercion: ImplicitCoercion,
597 },
598}
599
600impl Coercion {
601 pub fn new_exact(desired_type: TypeSignatureClass) -> Self {
602 Self::Exact { desired_type }
603 }
604
605 pub fn new_implicit(
610 desired_type: TypeSignatureClass,
611 allowed_source_types: Vec<TypeSignatureClass>,
612 default_casted_type: NativeType,
613 ) -> Self {
614 Self::Implicit {
615 desired_type,
616 implicit_coercion: ImplicitCoercion {
617 allowed_source_types,
618 default_casted_type,
619 },
620 }
621 }
622
623 pub fn allowed_source_types(&self) -> &[TypeSignatureClass] {
624 match self {
625 Coercion::Exact { .. } => &[],
626 Coercion::Implicit {
627 implicit_coercion, ..
628 } => implicit_coercion.allowed_source_types.as_slice(),
629 }
630 }
631
632 pub fn default_casted_type(&self) -> Option<&NativeType> {
633 match self {
634 Coercion::Exact { .. } => None,
635 Coercion::Implicit {
636 implicit_coercion, ..
637 } => Some(&implicit_coercion.default_casted_type),
638 }
639 }
640
641 pub fn desired_type(&self) -> &TypeSignatureClass {
642 match self {
643 Coercion::Exact { desired_type } => desired_type,
644 Coercion::Implicit { desired_type, .. } => desired_type,
645 }
646 }
647
648 pub fn implicit_coercion(&self) -> Option<&ImplicitCoercion> {
649 match self {
650 Coercion::Exact { .. } => None,
651 Coercion::Implicit {
652 implicit_coercion, ..
653 } => Some(implicit_coercion),
654 }
655 }
656}
657
658impl Display for Coercion {
659 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
660 write!(f, "Coercion({}", self.desired_type())?;
661 if let Some(implicit_coercion) = self.implicit_coercion() {
662 write!(f, ", implicit_coercion={implicit_coercion}",)
663 } else {
664 write!(f, ")")
665 }
666 }
667}
668
669impl PartialEq for Coercion {
670 fn eq(&self, other: &Self) -> bool {
671 self.desired_type() == other.desired_type()
672 && self.implicit_coercion() == other.implicit_coercion()
673 }
674}
675
676impl Hash for Coercion {
677 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
678 self.desired_type().hash(state);
679 self.implicit_coercion().hash(state);
680 }
681}
682
683#[derive(Debug, Clone, Eq, PartialOrd)]
705pub struct ImplicitCoercion {
706 allowed_source_types: Vec<TypeSignatureClass>,
708
709 default_casted_type: NativeType,
713}
714
715impl Display for ImplicitCoercion {
716 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
717 write!(
718 f,
719 "ImplicitCoercion({:?}, default_type={:?})",
720 self.allowed_source_types, self.default_casted_type
721 )
722 }
723}
724
725impl PartialEq for ImplicitCoercion {
726 fn eq(&self, other: &Self) -> bool {
727 self.allowed_source_types == other.allowed_source_types
728 && self.default_casted_type == other.default_casted_type
729 }
730}
731
732impl Hash for ImplicitCoercion {
733 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
734 self.allowed_source_types.hash(state);
735 self.default_casted_type.hash(state);
736 }
737}
738
739#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
744pub struct Signature {
745 pub type_signature: TypeSignature,
747 pub volatility: Volatility,
749}
750
751impl Signature {
752 pub fn new(type_signature: TypeSignature, volatility: Volatility) -> Self {
754 Signature {
755 type_signature,
756 volatility,
757 }
758 }
759 pub fn variadic(common_types: Vec<DataType>, volatility: Volatility) -> Self {
761 Self {
762 type_signature: TypeSignature::Variadic(common_types),
763 volatility,
764 }
765 }
766 pub fn user_defined(volatility: Volatility) -> Self {
768 Self {
769 type_signature: TypeSignature::UserDefined,
770 volatility,
771 }
772 }
773
774 pub fn numeric(arg_count: usize, volatility: Volatility) -> Self {
776 Self {
777 type_signature: TypeSignature::Numeric(arg_count),
778 volatility,
779 }
780 }
781
782 pub fn string(arg_count: usize, volatility: Volatility) -> Self {
784 Self {
785 type_signature: TypeSignature::String(arg_count),
786 volatility,
787 }
788 }
789
790 pub fn variadic_any(volatility: Volatility) -> Self {
792 Self {
793 type_signature: TypeSignature::VariadicAny,
794 volatility,
795 }
796 }
797 pub fn uniform(
799 arg_count: usize,
800 valid_types: Vec<DataType>,
801 volatility: Volatility,
802 ) -> Self {
803 Self {
804 type_signature: TypeSignature::Uniform(arg_count, valid_types),
805 volatility,
806 }
807 }
808 pub fn exact(exact_types: Vec<DataType>, volatility: Volatility) -> Self {
810 Signature {
811 type_signature: TypeSignature::Exact(exact_types),
812 volatility,
813 }
814 }
815
816 pub fn coercible(target_types: Vec<Coercion>, volatility: Volatility) -> Self {
818 Self {
819 type_signature: TypeSignature::Coercible(target_types),
820 volatility,
821 }
822 }
823
824 pub fn comparable(arg_count: usize, volatility: Volatility) -> Self {
826 Self {
827 type_signature: TypeSignature::Comparable(arg_count),
828 volatility,
829 }
830 }
831
832 pub fn nullary(volatility: Volatility) -> Self {
833 Signature {
834 type_signature: TypeSignature::Nullary,
835 volatility,
836 }
837 }
838
839 pub fn any(arg_count: usize, volatility: Volatility) -> Self {
841 Signature {
842 type_signature: TypeSignature::Any(arg_count),
843 volatility,
844 }
845 }
846
847 pub fn one_of(type_signatures: Vec<TypeSignature>, volatility: Volatility) -> Self {
849 Signature {
850 type_signature: TypeSignature::OneOf(type_signatures),
851 volatility,
852 }
853 }
854
855 pub fn array_and_element(volatility: Volatility) -> Self {
857 Signature {
858 type_signature: TypeSignature::ArraySignature(
859 ArrayFunctionSignature::Array {
860 arguments: vec![
861 ArrayFunctionArgument::Array,
862 ArrayFunctionArgument::Element,
863 ],
864 array_coercion: Some(ListCoercion::FixedSizedListToList),
865 },
866 ),
867 volatility,
868 }
869 }
870
871 pub fn element_and_array(volatility: Volatility) -> Self {
873 Signature {
874 type_signature: TypeSignature::ArraySignature(
875 ArrayFunctionSignature::Array {
876 arguments: vec![
877 ArrayFunctionArgument::Element,
878 ArrayFunctionArgument::Array,
879 ],
880 array_coercion: Some(ListCoercion::FixedSizedListToList),
881 },
882 ),
883 volatility,
884 }
885 }
886
887 pub fn arrays(
889 n: usize,
890 coercion: Option<ListCoercion>,
891 volatility: Volatility,
892 ) -> Self {
893 Signature {
894 type_signature: TypeSignature::ArraySignature(
895 ArrayFunctionSignature::Array {
896 arguments: vec![ArrayFunctionArgument::Array; n],
897 array_coercion: coercion,
898 },
899 ),
900 volatility,
901 }
902 }
903
904 pub fn array_and_element_and_optional_index(volatility: Volatility) -> Self {
906 Signature {
907 type_signature: TypeSignature::OneOf(vec![
908 TypeSignature::ArraySignature(ArrayFunctionSignature::Array {
909 arguments: vec![
910 ArrayFunctionArgument::Array,
911 ArrayFunctionArgument::Element,
912 ],
913 array_coercion: None,
914 }),
915 TypeSignature::ArraySignature(ArrayFunctionSignature::Array {
916 arguments: vec![
917 ArrayFunctionArgument::Array,
918 ArrayFunctionArgument::Element,
919 ArrayFunctionArgument::Index,
920 ],
921 array_coercion: None,
922 }),
923 ]),
924 volatility,
925 }
926 }
927
928 pub fn array_and_index(volatility: Volatility) -> Self {
930 Signature {
931 type_signature: TypeSignature::ArraySignature(
932 ArrayFunctionSignature::Array {
933 arguments: vec![
934 ArrayFunctionArgument::Array,
935 ArrayFunctionArgument::Index,
936 ],
937 array_coercion: Some(ListCoercion::FixedSizedListToList),
938 },
939 ),
940 volatility,
941 }
942 }
943
944 pub fn array(volatility: Volatility) -> Self {
946 Signature::arrays(1, Some(ListCoercion::FixedSizedListToList), volatility)
947 }
948}
949
950#[cfg(test)]
951mod tests {
952 use datafusion_common::types::{logical_int64, logical_string};
953
954 use super::*;
955
956 #[test]
957 fn supports_zero_argument_tests() {
958 let positive_cases = vec![
960 TypeSignature::Exact(vec![]),
961 TypeSignature::OneOf(vec![
962 TypeSignature::Exact(vec![DataType::Int8]),
963 TypeSignature::Nullary,
964 TypeSignature::Uniform(1, vec![DataType::Int8]),
965 ]),
966 TypeSignature::Nullary,
967 ];
968
969 for case in positive_cases {
970 assert!(
971 case.supports_zero_argument(),
972 "Expected {case:?} to support zero arguments"
973 );
974 }
975
976 let negative_cases = vec![
978 TypeSignature::Exact(vec![DataType::Utf8]),
979 TypeSignature::Uniform(1, vec![DataType::Float64]),
980 TypeSignature::Any(1),
981 TypeSignature::VariadicAny,
982 TypeSignature::OneOf(vec![
983 TypeSignature::Exact(vec![DataType::Int8]),
984 TypeSignature::Uniform(1, vec![DataType::Int8]),
985 ]),
986 ];
987
988 for case in negative_cases {
989 assert!(
990 !case.supports_zero_argument(),
991 "Expected {case:?} not to support zero arguments"
992 );
993 }
994 }
995
996 #[test]
997 fn type_signature_partial_ord() {
998 assert!(TypeSignature::UserDefined < TypeSignature::VariadicAny);
1000 assert!(TypeSignature::UserDefined < TypeSignature::Any(1));
1001
1002 assert!(
1003 TypeSignature::Uniform(1, vec![DataType::Null])
1004 < TypeSignature::Uniform(1, vec![DataType::Boolean])
1005 );
1006 assert!(
1007 TypeSignature::Uniform(1, vec![DataType::Null])
1008 < TypeSignature::Uniform(2, vec![DataType::Null])
1009 );
1010 assert!(
1011 TypeSignature::Uniform(usize::MAX, vec![DataType::Null])
1012 < TypeSignature::Exact(vec![DataType::Null])
1013 );
1014 }
1015
1016 #[test]
1017 fn test_get_possible_types() {
1018 let type_signature = TypeSignature::Exact(vec![DataType::Int32, DataType::Int64]);
1019 let possible_types = type_signature.get_example_types();
1020 assert_eq!(possible_types, vec![vec![DataType::Int32, DataType::Int64]]);
1021
1022 let type_signature = TypeSignature::OneOf(vec![
1023 TypeSignature::Exact(vec![DataType::Int32, DataType::Int64]),
1024 TypeSignature::Exact(vec![DataType::Float32, DataType::Float64]),
1025 ]);
1026 let possible_types = type_signature.get_example_types();
1027 assert_eq!(
1028 possible_types,
1029 vec![
1030 vec![DataType::Int32, DataType::Int64],
1031 vec![DataType::Float32, DataType::Float64]
1032 ]
1033 );
1034
1035 let type_signature = TypeSignature::OneOf(vec![
1036 TypeSignature::Exact(vec![DataType::Int32, DataType::Int64]),
1037 TypeSignature::Exact(vec![DataType::Float32, DataType::Float64]),
1038 TypeSignature::Exact(vec![DataType::Utf8]),
1039 ]);
1040 let possible_types = type_signature.get_example_types();
1041 assert_eq!(
1042 possible_types,
1043 vec![
1044 vec![DataType::Int32, DataType::Int64],
1045 vec![DataType::Float32, DataType::Float64],
1046 vec![DataType::Utf8]
1047 ]
1048 );
1049
1050 let type_signature =
1051 TypeSignature::Uniform(2, vec![DataType::Float32, DataType::Int64]);
1052 let possible_types = type_signature.get_example_types();
1053 assert_eq!(
1054 possible_types,
1055 vec![
1056 vec![DataType::Float32, DataType::Float32],
1057 vec![DataType::Int64, DataType::Int64]
1058 ]
1059 );
1060
1061 let type_signature = TypeSignature::Coercible(vec![
1062 Coercion::new_exact(TypeSignatureClass::Native(logical_string())),
1063 Coercion::new_exact(TypeSignatureClass::Native(logical_int64())),
1064 ]);
1065 let possible_types = type_signature.get_example_types();
1066 assert_eq!(
1067 possible_types,
1068 vec![
1069 vec![DataType::Utf8, DataType::Int64],
1070 vec![DataType::LargeUtf8, DataType::Int64],
1071 vec![DataType::Utf8View, DataType::Int64]
1072 ]
1073 );
1074
1075 let type_signature =
1076 TypeSignature::Variadic(vec![DataType::Int32, DataType::Int64]);
1077 let possible_types = type_signature.get_example_types();
1078 assert_eq!(
1079 possible_types,
1080 vec![vec![DataType::Int32], vec![DataType::Int64]]
1081 );
1082
1083 let type_signature = TypeSignature::Numeric(2);
1084 let possible_types = type_signature.get_example_types();
1085 assert_eq!(
1086 possible_types,
1087 vec![
1088 vec![DataType::Int8, DataType::Int8],
1089 vec![DataType::Int16, DataType::Int16],
1090 vec![DataType::Int32, DataType::Int32],
1091 vec![DataType::Int64, DataType::Int64],
1092 vec![DataType::UInt8, DataType::UInt8],
1093 vec![DataType::UInt16, DataType::UInt16],
1094 vec![DataType::UInt32, DataType::UInt32],
1095 vec![DataType::UInt64, DataType::UInt64],
1096 vec![DataType::Float32, DataType::Float32],
1097 vec![DataType::Float64, DataType::Float64]
1098 ]
1099 );
1100
1101 let type_signature = TypeSignature::String(2);
1102 let possible_types = type_signature.get_example_types();
1103 assert_eq!(
1104 possible_types,
1105 vec![
1106 vec![DataType::Utf8, DataType::Utf8],
1107 vec![DataType::LargeUtf8, DataType::LargeUtf8],
1108 vec![DataType::Utf8View, DataType::Utf8View]
1109 ]
1110 );
1111 }
1112}