1use std::fmt::Display;
21use std::hash::Hash;
22
23use crate::type_coercion::aggregates::NUMERICS;
24use arrow::datatypes::{DataType, IntervalUnit, TimeUnit};
25use datafusion_common::types::{LogicalType, LogicalTypeRef, NativeType};
26use datafusion_common::utils::ListCoercion;
27use datafusion_common::{internal_err, plan_err, Result};
28use indexmap::IndexSet;
29use itertools::Itertools;
30
31pub const TIMEZONE_WILDCARD: &str = "+TZ";
40
41pub const FIXED_SIZE_LIST_WILDCARD: i32 = i32::MIN;
45
46#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
53pub enum Volatility {
54 Immutable,
62 Stable,
74 Volatile,
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89pub enum Arity {
90 Fixed(usize),
92 Variable,
94}
95
96#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
154pub enum TypeSignature {
155 Variadic(Vec<DataType>),
164 UserDefined,
172 VariadicAny,
174 Uniform(usize, Vec<DataType>),
181 Exact(Vec<DataType>),
185 Coercible(Vec<Coercion>),
193 Comparable(usize),
212 Any(usize),
216 OneOf(Vec<TypeSignature>),
226 ArraySignature(ArrayFunctionSignature),
228 Numeric(usize),
236 String(usize),
247 Nullary,
249}
250
251impl TypeSignature {
252 #[inline]
253 pub fn is_one_of(&self) -> bool {
254 matches!(self, TypeSignature::OneOf(_))
255 }
256
257 pub fn arity(&self) -> Arity {
276 match self {
277 TypeSignature::Exact(types) => Arity::Fixed(types.len()),
278 TypeSignature::Uniform(count, _) => Arity::Fixed(*count),
279 TypeSignature::Numeric(count) => Arity::Fixed(*count),
280 TypeSignature::String(count) => Arity::Fixed(*count),
281 TypeSignature::Comparable(count) => Arity::Fixed(*count),
282 TypeSignature::Any(count) => Arity::Fixed(*count),
283 TypeSignature::Coercible(types) => Arity::Fixed(types.len()),
284 TypeSignature::Nullary => Arity::Fixed(0),
285 TypeSignature::ArraySignature(ArrayFunctionSignature::Array {
286 arguments,
287 ..
288 }) => Arity::Fixed(arguments.len()),
289 TypeSignature::ArraySignature(ArrayFunctionSignature::RecursiveArray) => {
290 Arity::Fixed(1)
291 }
292 TypeSignature::ArraySignature(ArrayFunctionSignature::MapArray) => {
293 Arity::Fixed(1)
294 }
295 TypeSignature::OneOf(variants) => {
296 let has_variable = variants.iter().any(|v| v.arity() == Arity::Variable);
298 if has_variable {
299 return Arity::Variable;
300 }
301 let max_arity = variants
303 .iter()
304 .filter_map(|v| match v.arity() {
305 Arity::Fixed(n) => Some(n),
306 Arity::Variable => None,
307 })
308 .max();
309 match max_arity {
310 Some(n) => Arity::Fixed(n),
311 None => Arity::Variable,
312 }
313 }
314 TypeSignature::Variadic(_)
315 | TypeSignature::VariadicAny
316 | TypeSignature::UserDefined => Arity::Variable,
317 }
318 }
319}
320
321#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Hash)]
330pub enum TypeSignatureClass {
331 Timestamp,
332 Time,
333 Interval,
334 Duration,
335 Native(LogicalTypeRef),
336 Integer,
339 Binary,
341}
342
343impl Display for TypeSignatureClass {
344 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
345 write!(f, "TypeSignatureClass::{self:?}")
346 }
347}
348
349impl TypeSignatureClass {
350 fn get_example_types(&self) -> Vec<DataType> {
355 match self {
356 TypeSignatureClass::Native(l) => get_data_types(l.native()),
357 TypeSignatureClass::Timestamp => {
358 vec![
359 DataType::Timestamp(TimeUnit::Nanosecond, None),
360 DataType::Timestamp(
361 TimeUnit::Nanosecond,
362 Some(TIMEZONE_WILDCARD.into()),
363 ),
364 ]
365 }
366 TypeSignatureClass::Time => {
367 vec![DataType::Time64(TimeUnit::Nanosecond)]
368 }
369 TypeSignatureClass::Interval => {
370 vec![DataType::Interval(IntervalUnit::DayTime)]
371 }
372 TypeSignatureClass::Duration => {
373 vec![DataType::Duration(TimeUnit::Nanosecond)]
374 }
375 TypeSignatureClass::Integer => {
376 vec![DataType::Int64]
377 }
378 TypeSignatureClass::Binary => {
379 vec![DataType::Binary]
380 }
381 }
382 }
383
384 pub fn matches_native_type(&self, logical_type: &NativeType) -> bool {
386 if logical_type == &NativeType::Null {
387 return true;
388 }
389
390 match self {
391 TypeSignatureClass::Native(t) if t.native() == logical_type => true,
392 TypeSignatureClass::Timestamp if logical_type.is_timestamp() => true,
393 TypeSignatureClass::Time if logical_type.is_time() => true,
394 TypeSignatureClass::Interval if logical_type.is_interval() => true,
395 TypeSignatureClass::Duration if logical_type.is_duration() => true,
396 TypeSignatureClass::Integer if logical_type.is_integer() => true,
397 TypeSignatureClass::Binary if logical_type.is_binary() => true,
398 _ => false,
399 }
400 }
401
402 pub fn default_casted_type(
404 &self,
405 native_type: &NativeType,
406 origin_type: &DataType,
407 ) -> Result<DataType> {
408 match self {
409 TypeSignatureClass::Native(logical_type) => {
410 logical_type.native().default_cast_for(origin_type)
411 }
412 TypeSignatureClass::Timestamp if native_type.is_timestamp() => {
414 Ok(origin_type.to_owned())
415 }
416 TypeSignatureClass::Time if native_type.is_time() => {
417 Ok(origin_type.to_owned())
418 }
419 TypeSignatureClass::Interval if native_type.is_interval() => {
420 Ok(origin_type.to_owned())
421 }
422 TypeSignatureClass::Duration if native_type.is_duration() => {
423 Ok(origin_type.to_owned())
424 }
425 TypeSignatureClass::Integer if native_type.is_integer() => {
426 Ok(origin_type.to_owned())
427 }
428 TypeSignatureClass::Binary if native_type.is_binary() => {
429 Ok(origin_type.to_owned())
430 }
431 _ if native_type.is_null() => Ok(origin_type.to_owned()),
432 _ => internal_err!("May miss the matching logic in `matches_native_type`"),
433 }
434 }
435}
436
437#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
438pub enum ArrayFunctionSignature {
439 Array {
441 arguments: Vec<ArrayFunctionArgument>,
443 array_coercion: Option<ListCoercion>,
445 },
446 RecursiveArray,
449 MapArray,
452}
453
454impl Display for ArrayFunctionSignature {
455 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
456 match self {
457 ArrayFunctionSignature::Array { arguments, .. } => {
458 for (idx, argument) in arguments.iter().enumerate() {
459 write!(f, "{argument}")?;
460 if idx != arguments.len() - 1 {
461 write!(f, ", ")?;
462 }
463 }
464 Ok(())
465 }
466 ArrayFunctionSignature::RecursiveArray => {
467 write!(f, "recursive_array")
468 }
469 ArrayFunctionSignature::MapArray => {
470 write!(f, "map_array")
471 }
472 }
473 }
474}
475
476#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
477pub enum ArrayFunctionArgument {
478 Element,
481 Index,
483 Array,
486 String,
488}
489
490impl Display for ArrayFunctionArgument {
491 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
492 match self {
493 ArrayFunctionArgument::Element => {
494 write!(f, "element")
495 }
496 ArrayFunctionArgument::Index => {
497 write!(f, "index")
498 }
499 ArrayFunctionArgument::Array => {
500 write!(f, "array")
501 }
502 ArrayFunctionArgument::String => {
503 write!(f, "string")
504 }
505 }
506 }
507}
508
509impl TypeSignature {
510 pub fn to_string_repr(&self) -> Vec<String> {
511 match self {
512 TypeSignature::Nullary => {
513 vec!["NullAry()".to_string()]
514 }
515 TypeSignature::Variadic(types) => {
516 vec![format!("{}, ..", Self::join_types(types, "/"))]
517 }
518 TypeSignature::Uniform(arg_count, valid_types) => {
519 vec![
520 std::iter::repeat_n(Self::join_types(valid_types, "/"), *arg_count)
521 .collect::<Vec<String>>()
522 .join(", "),
523 ]
524 }
525 TypeSignature::String(num) => {
526 vec![format!("String({num})")]
527 }
528 TypeSignature::Numeric(num) => {
529 vec![format!("Numeric({num})")]
530 }
531 TypeSignature::Comparable(num) => {
532 vec![format!("Comparable({num})")]
533 }
534 TypeSignature::Coercible(coercions) => {
535 vec![Self::join_types(coercions, ", ")]
536 }
537 TypeSignature::Exact(types) => {
538 vec![Self::join_types(types, ", ")]
539 }
540 TypeSignature::Any(arg_count) => {
541 vec![std::iter::repeat_n("Any", *arg_count)
542 .collect::<Vec<&str>>()
543 .join(", ")]
544 }
545 TypeSignature::UserDefined => {
546 vec!["UserDefined".to_string()]
547 }
548 TypeSignature::VariadicAny => vec!["Any, .., Any".to_string()],
549 TypeSignature::OneOf(sigs) => {
550 sigs.iter().flat_map(|s| s.to_string_repr()).collect()
551 }
552 TypeSignature::ArraySignature(array_signature) => {
553 vec![array_signature.to_string()]
554 }
555 }
556 }
557
558 pub fn to_string_repr_with_names(
584 &self,
585 parameter_names: Option<&[String]>,
586 ) -> Vec<String> {
587 match self {
588 TypeSignature::Exact(types) => {
589 if let Some(names) = parameter_names {
590 vec![names
591 .iter()
592 .zip(types.iter())
593 .map(|(name, typ)| format!("{name}: {typ}"))
594 .collect::<Vec<_>>()
595 .join(", ")]
596 } else {
597 vec![Self::join_types(types, ", ")]
598 }
599 }
600 TypeSignature::Any(count) => {
601 if let Some(names) = parameter_names {
602 vec![names
603 .iter()
604 .take(*count)
605 .map(|name| format!("{name}: Any"))
606 .collect::<Vec<_>>()
607 .join(", ")]
608 } else {
609 vec![std::iter::repeat_n("Any", *count)
610 .collect::<Vec<&str>>()
611 .join(", ")]
612 }
613 }
614 TypeSignature::Uniform(count, types) => {
615 if let Some(names) = parameter_names {
616 let type_str = Self::join_types(types, "/");
617 vec![names
618 .iter()
619 .take(*count)
620 .map(|name| format!("{name}: {type_str}"))
621 .collect::<Vec<_>>()
622 .join(", ")]
623 } else {
624 self.to_string_repr()
625 }
626 }
627 TypeSignature::Coercible(coercions) => {
628 if let Some(names) = parameter_names {
629 vec![names
630 .iter()
631 .zip(coercions.iter())
632 .map(|(name, coercion)| format!("{name}: {coercion}"))
633 .collect::<Vec<_>>()
634 .join(", ")]
635 } else {
636 vec![Self::join_types(coercions, ", ")]
637 }
638 }
639 TypeSignature::Comparable(count) => {
640 if let Some(names) = parameter_names {
641 vec![names
642 .iter()
643 .take(*count)
644 .map(|name| format!("{name}: Comparable"))
645 .collect::<Vec<_>>()
646 .join(", ")]
647 } else {
648 self.to_string_repr()
649 }
650 }
651 TypeSignature::Numeric(count) => {
652 if let Some(names) = parameter_names {
653 vec![names
654 .iter()
655 .take(*count)
656 .map(|name| format!("{name}: Numeric"))
657 .collect::<Vec<_>>()
658 .join(", ")]
659 } else {
660 self.to_string_repr()
661 }
662 }
663 TypeSignature::String(count) => {
664 if let Some(names) = parameter_names {
665 vec![names
666 .iter()
667 .take(*count)
668 .map(|name| format!("{name}: String"))
669 .collect::<Vec<_>>()
670 .join(", ")]
671 } else {
672 self.to_string_repr()
673 }
674 }
675 TypeSignature::Nullary => self.to_string_repr(),
676 TypeSignature::ArraySignature(array_sig) => {
677 if let Some(names) = parameter_names {
678 match array_sig {
679 ArrayFunctionSignature::Array { arguments, .. } => {
680 vec![names
681 .iter()
682 .zip(arguments.iter())
683 .map(|(name, arg_type)| format!("{name}: {arg_type}"))
684 .collect::<Vec<_>>()
685 .join(", ")]
686 }
687 ArrayFunctionSignature::RecursiveArray => {
688 vec![names
689 .iter()
690 .take(1)
691 .map(|name| format!("{name}: recursive_array"))
692 .collect::<Vec<_>>()
693 .join(", ")]
694 }
695 ArrayFunctionSignature::MapArray => {
696 vec![names
697 .iter()
698 .take(1)
699 .map(|name| format!("{name}: map_array"))
700 .collect::<Vec<_>>()
701 .join(", ")]
702 }
703 }
704 } else {
705 self.to_string_repr()
706 }
707 }
708 TypeSignature::OneOf(sigs) => sigs
709 .iter()
710 .flat_map(|s| s.to_string_repr_with_names(parameter_names))
711 .collect(),
712 TypeSignature::UserDefined => {
713 if let Some(names) = parameter_names {
714 vec![names.join(", ")]
715 } else {
716 self.to_string_repr()
717 }
718 }
719 TypeSignature::Variadic(_) | TypeSignature::VariadicAny => {
721 self.to_string_repr()
722 }
723 }
724 }
725
726 pub fn join_types<T: Display>(types: &[T], delimiter: &str) -> String {
728 types
729 .iter()
730 .map(|t| t.to_string())
731 .collect::<Vec<String>>()
732 .join(delimiter)
733 }
734
735 pub fn supports_zero_argument(&self) -> bool {
737 match &self {
738 TypeSignature::Exact(vec) => vec.is_empty(),
739 TypeSignature::Nullary => true,
740 TypeSignature::OneOf(types) => types
741 .iter()
742 .any(|type_sig| type_sig.supports_zero_argument()),
743 _ => false,
744 }
745 }
746
747 pub fn used_to_support_zero_arguments(&self) -> bool {
750 match &self {
751 TypeSignature::Any(num) => *num == 0,
752 _ => self.supports_zero_argument(),
753 }
754 }
755
756 #[deprecated(since = "46.0.0", note = "See get_example_types instead")]
757 pub fn get_possible_types(&self) -> Vec<Vec<DataType>> {
758 self.get_example_types()
759 }
760
761 pub fn get_example_types(&self) -> Vec<Vec<DataType>> {
768 match self {
769 TypeSignature::Exact(types) => vec![types.clone()],
770 TypeSignature::OneOf(types) => types
771 .iter()
772 .flat_map(|type_sig| type_sig.get_example_types())
773 .collect(),
774 TypeSignature::Uniform(arg_count, types) => types
775 .iter()
776 .cloned()
777 .map(|data_type| vec![data_type; *arg_count])
778 .collect(),
779 TypeSignature::Coercible(coercions) => coercions
780 .iter()
781 .map(|c| {
782 let mut all_types: IndexSet<DataType> =
783 c.desired_type().get_example_types().into_iter().collect();
784
785 if let Some(implicit_coercion) = c.implicit_coercion() {
786 let allowed_casts: Vec<DataType> = implicit_coercion
787 .allowed_source_types
788 .iter()
789 .flat_map(|t| t.get_example_types())
790 .collect();
791 all_types.extend(allowed_casts);
792 }
793
794 all_types.into_iter().collect::<Vec<_>>()
795 })
796 .multi_cartesian_product()
797 .collect(),
798 TypeSignature::Variadic(types) => types
799 .iter()
800 .cloned()
801 .map(|data_type| vec![data_type])
802 .collect(),
803 TypeSignature::Numeric(arg_count) => NUMERICS
804 .iter()
805 .cloned()
806 .map(|numeric_type| vec![numeric_type; *arg_count])
807 .collect(),
808 TypeSignature::String(arg_count) => get_data_types(&NativeType::String)
809 .into_iter()
810 .map(|dt| vec![dt; *arg_count])
811 .collect::<Vec<_>>(),
812 TypeSignature::Any(_)
814 | TypeSignature::Comparable(_)
815 | TypeSignature::Nullary
816 | TypeSignature::VariadicAny
817 | TypeSignature::ArraySignature(_)
818 | TypeSignature::UserDefined => vec![],
819 }
820 }
821}
822
823fn get_data_types(native_type: &NativeType) -> Vec<DataType> {
824 match native_type {
825 NativeType::Null => vec![DataType::Null],
826 NativeType::Boolean => vec![DataType::Boolean],
827 NativeType::Int8 => vec![DataType::Int8],
828 NativeType::Int16 => vec![DataType::Int16],
829 NativeType::Int32 => vec![DataType::Int32],
830 NativeType::Int64 => vec![DataType::Int64],
831 NativeType::UInt8 => vec![DataType::UInt8],
832 NativeType::UInt16 => vec![DataType::UInt16],
833 NativeType::UInt32 => vec![DataType::UInt32],
834 NativeType::UInt64 => vec![DataType::UInt64],
835 NativeType::Float16 => vec![DataType::Float16],
836 NativeType::Float32 => vec![DataType::Float32],
837 NativeType::Float64 => vec![DataType::Float64],
838 NativeType::Date => vec![DataType::Date32, DataType::Date64],
839 NativeType::Binary => vec![
840 DataType::Binary,
841 DataType::LargeBinary,
842 DataType::BinaryView,
843 ],
844 NativeType::String => {
845 vec![DataType::Utf8, DataType::LargeUtf8, DataType::Utf8View]
846 }
847 _ => vec![],
849 }
850}
851
852#[derive(Debug, Clone, Eq, PartialOrd)]
877pub enum Coercion {
878 Exact {
880 desired_type: TypeSignatureClass,
882 },
883
884 Implicit {
886 desired_type: TypeSignatureClass,
888 implicit_coercion: ImplicitCoercion,
890 },
891}
892
893impl Coercion {
894 pub fn new_exact(desired_type: TypeSignatureClass) -> Self {
895 Self::Exact { desired_type }
896 }
897
898 pub fn new_implicit(
903 desired_type: TypeSignatureClass,
904 allowed_source_types: Vec<TypeSignatureClass>,
905 default_casted_type: NativeType,
906 ) -> Self {
907 Self::Implicit {
908 desired_type,
909 implicit_coercion: ImplicitCoercion {
910 allowed_source_types,
911 default_casted_type,
912 },
913 }
914 }
915
916 pub fn allowed_source_types(&self) -> &[TypeSignatureClass] {
917 match self {
918 Coercion::Exact { .. } => &[],
919 Coercion::Implicit {
920 implicit_coercion, ..
921 } => implicit_coercion.allowed_source_types.as_slice(),
922 }
923 }
924
925 pub fn default_casted_type(&self) -> Option<&NativeType> {
926 match self {
927 Coercion::Exact { .. } => None,
928 Coercion::Implicit {
929 implicit_coercion, ..
930 } => Some(&implicit_coercion.default_casted_type),
931 }
932 }
933
934 pub fn desired_type(&self) -> &TypeSignatureClass {
935 match self {
936 Coercion::Exact { desired_type } => desired_type,
937 Coercion::Implicit { desired_type, .. } => desired_type,
938 }
939 }
940
941 pub fn implicit_coercion(&self) -> Option<&ImplicitCoercion> {
942 match self {
943 Coercion::Exact { .. } => None,
944 Coercion::Implicit {
945 implicit_coercion, ..
946 } => Some(implicit_coercion),
947 }
948 }
949}
950
951impl Display for Coercion {
952 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
953 write!(f, "Coercion({}", self.desired_type())?;
954 if let Some(implicit_coercion) = self.implicit_coercion() {
955 write!(f, ", implicit_coercion={implicit_coercion}",)
956 } else {
957 write!(f, ")")
958 }
959 }
960}
961
962impl PartialEq for Coercion {
963 fn eq(&self, other: &Self) -> bool {
964 self.desired_type() == other.desired_type()
965 && self.implicit_coercion() == other.implicit_coercion()
966 }
967}
968
969impl Hash for Coercion {
970 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
971 self.desired_type().hash(state);
972 self.implicit_coercion().hash(state);
973 }
974}
975
976#[derive(Debug, Clone, Eq, PartialOrd)]
998pub struct ImplicitCoercion {
999 allowed_source_types: Vec<TypeSignatureClass>,
1001
1002 default_casted_type: NativeType,
1006}
1007
1008impl Display for ImplicitCoercion {
1009 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1010 write!(
1011 f,
1012 "ImplicitCoercion({:?}, default_type={:?})",
1013 self.allowed_source_types, self.default_casted_type
1014 )
1015 }
1016}
1017
1018impl PartialEq for ImplicitCoercion {
1019 fn eq(&self, other: &Self) -> bool {
1020 self.allowed_source_types == other.allowed_source_types
1021 && self.default_casted_type == other.default_casted_type
1022 }
1023}
1024
1025impl Hash for ImplicitCoercion {
1026 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1027 self.allowed_source_types.hash(state);
1028 self.default_casted_type.hash(state);
1029 }
1030}
1031
1032#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
1039pub struct Signature {
1040 pub type_signature: TypeSignature,
1042 pub volatility: Volatility,
1044 pub parameter_names: Option<Vec<String>>,
1051}
1052
1053impl Signature {
1054 pub fn new(type_signature: TypeSignature, volatility: Volatility) -> Self {
1056 Signature {
1057 type_signature,
1058 volatility,
1059 parameter_names: None,
1060 }
1061 }
1062 pub fn variadic(common_types: Vec<DataType>, volatility: Volatility) -> Self {
1064 Self {
1065 type_signature: TypeSignature::Variadic(common_types),
1066 volatility,
1067 parameter_names: None,
1068 }
1069 }
1070 pub fn user_defined(volatility: Volatility) -> Self {
1072 Self {
1073 type_signature: TypeSignature::UserDefined,
1074 volatility,
1075 parameter_names: None,
1076 }
1077 }
1078
1079 pub fn numeric(arg_count: usize, volatility: Volatility) -> Self {
1081 Self {
1082 type_signature: TypeSignature::Numeric(arg_count),
1083 volatility,
1084 parameter_names: None,
1085 }
1086 }
1087
1088 pub fn string(arg_count: usize, volatility: Volatility) -> Self {
1090 Self {
1091 type_signature: TypeSignature::String(arg_count),
1092 volatility,
1093 parameter_names: None,
1094 }
1095 }
1096
1097 pub fn variadic_any(volatility: Volatility) -> Self {
1099 Self {
1100 type_signature: TypeSignature::VariadicAny,
1101 volatility,
1102 parameter_names: None,
1103 }
1104 }
1105 pub fn uniform(
1107 arg_count: usize,
1108 valid_types: Vec<DataType>,
1109 volatility: Volatility,
1110 ) -> Self {
1111 Self {
1112 type_signature: TypeSignature::Uniform(arg_count, valid_types),
1113 volatility,
1114 parameter_names: None,
1115 }
1116 }
1117 pub fn exact(exact_types: Vec<DataType>, volatility: Volatility) -> Self {
1119 Signature {
1120 type_signature: TypeSignature::Exact(exact_types),
1121 volatility,
1122 parameter_names: None,
1123 }
1124 }
1125
1126 pub fn coercible(target_types: Vec<Coercion>, volatility: Volatility) -> Self {
1128 Self {
1129 type_signature: TypeSignature::Coercible(target_types),
1130 volatility,
1131 parameter_names: None,
1132 }
1133 }
1134
1135 pub fn comparable(arg_count: usize, volatility: Volatility) -> Self {
1137 Self {
1138 type_signature: TypeSignature::Comparable(arg_count),
1139 volatility,
1140 parameter_names: None,
1141 }
1142 }
1143
1144 pub fn nullary(volatility: Volatility) -> Self {
1145 Signature {
1146 type_signature: TypeSignature::Nullary,
1147 volatility,
1148 parameter_names: None,
1149 }
1150 }
1151
1152 pub fn any(arg_count: usize, volatility: Volatility) -> Self {
1154 Signature {
1155 type_signature: TypeSignature::Any(arg_count),
1156 volatility,
1157 parameter_names: None,
1158 }
1159 }
1160
1161 pub fn one_of(type_signatures: Vec<TypeSignature>, volatility: Volatility) -> Self {
1163 Signature {
1164 type_signature: TypeSignature::OneOf(type_signatures),
1165 volatility,
1166 parameter_names: None,
1167 }
1168 }
1169
1170 pub fn array_and_element(volatility: Volatility) -> Self {
1172 Signature {
1173 type_signature: TypeSignature::ArraySignature(
1174 ArrayFunctionSignature::Array {
1175 arguments: vec![
1176 ArrayFunctionArgument::Array,
1177 ArrayFunctionArgument::Element,
1178 ],
1179 array_coercion: Some(ListCoercion::FixedSizedListToList),
1180 },
1181 ),
1182 volatility,
1183 parameter_names: None,
1184 }
1185 }
1186
1187 pub fn element_and_array(volatility: Volatility) -> Self {
1189 Signature {
1190 type_signature: TypeSignature::ArraySignature(
1191 ArrayFunctionSignature::Array {
1192 arguments: vec![
1193 ArrayFunctionArgument::Element,
1194 ArrayFunctionArgument::Array,
1195 ],
1196 array_coercion: Some(ListCoercion::FixedSizedListToList),
1197 },
1198 ),
1199 volatility,
1200 parameter_names: None,
1201 }
1202 }
1203
1204 pub fn arrays(
1206 n: usize,
1207 coercion: Option<ListCoercion>,
1208 volatility: Volatility,
1209 ) -> Self {
1210 Signature {
1211 type_signature: TypeSignature::ArraySignature(
1212 ArrayFunctionSignature::Array {
1213 arguments: vec![ArrayFunctionArgument::Array; n],
1214 array_coercion: coercion,
1215 },
1216 ),
1217 volatility,
1218 parameter_names: None,
1219 }
1220 }
1221
1222 pub fn array_and_element_and_optional_index(volatility: Volatility) -> Self {
1224 Signature {
1225 type_signature: TypeSignature::OneOf(vec![
1226 TypeSignature::ArraySignature(ArrayFunctionSignature::Array {
1227 arguments: vec![
1228 ArrayFunctionArgument::Array,
1229 ArrayFunctionArgument::Element,
1230 ],
1231 array_coercion: Some(ListCoercion::FixedSizedListToList),
1232 }),
1233 TypeSignature::ArraySignature(ArrayFunctionSignature::Array {
1234 arguments: vec![
1235 ArrayFunctionArgument::Array,
1236 ArrayFunctionArgument::Element,
1237 ArrayFunctionArgument::Index,
1238 ],
1239 array_coercion: Some(ListCoercion::FixedSizedListToList),
1240 }),
1241 ]),
1242 volatility,
1243 parameter_names: None,
1244 }
1245 }
1246
1247 pub fn array_and_index(volatility: Volatility) -> Self {
1249 Signature {
1250 type_signature: TypeSignature::ArraySignature(
1251 ArrayFunctionSignature::Array {
1252 arguments: vec![
1253 ArrayFunctionArgument::Array,
1254 ArrayFunctionArgument::Index,
1255 ],
1256 array_coercion: Some(ListCoercion::FixedSizedListToList),
1257 },
1258 ),
1259 volatility,
1260 parameter_names: None,
1261 }
1262 }
1263
1264 pub fn array(volatility: Volatility) -> Self {
1266 Signature::arrays(1, Some(ListCoercion::FixedSizedListToList), volatility)
1267 }
1268
1269 pub fn with_parameter_names(mut self, names: Vec<impl Into<String>>) -> Result<Self> {
1285 let names = names.into_iter().map(Into::into).collect::<Vec<String>>();
1286 self.validate_parameter_names(&names)?;
1288 self.parameter_names = Some(names);
1289 Ok(self)
1290 }
1291
1292 fn validate_parameter_names(&self, names: &[String]) -> Result<()> {
1294 match self.type_signature.arity() {
1295 Arity::Fixed(expected) => {
1296 if names.len() != expected {
1297 return plan_err!(
1298 "Parameter names count ({}) does not match signature arity ({})",
1299 names.len(),
1300 expected
1301 );
1302 }
1303 }
1304 Arity::Variable => {
1305 if !matches!(self.type_signature, TypeSignature::UserDefined) {
1308 return plan_err!(
1309 "Cannot specify parameter names for variable arity signature: {:?}",
1310 self.type_signature
1311 );
1312 }
1313 }
1314 }
1315
1316 let mut seen = std::collections::HashSet::new();
1317 for name in names {
1318 if !seen.insert(name) {
1319 return plan_err!("Duplicate parameter name: '{}'", name);
1320 }
1321 }
1322
1323 Ok(())
1324 }
1325}
1326
1327#[cfg(test)]
1328mod tests {
1329 use datafusion_common::types::{logical_int32, logical_int64, logical_string};
1330
1331 use super::*;
1332 use crate::signature::{
1333 ArrayFunctionArgument, ArrayFunctionSignature, Coercion, TypeSignatureClass,
1334 };
1335
1336 #[test]
1337 fn supports_zero_argument_tests() {
1338 let positive_cases = vec![
1340 TypeSignature::Exact(vec![]),
1341 TypeSignature::OneOf(vec![
1342 TypeSignature::Exact(vec![DataType::Int8]),
1343 TypeSignature::Nullary,
1344 TypeSignature::Uniform(1, vec![DataType::Int8]),
1345 ]),
1346 TypeSignature::Nullary,
1347 ];
1348
1349 for case in positive_cases {
1350 assert!(
1351 case.supports_zero_argument(),
1352 "Expected {case:?} to support zero arguments"
1353 );
1354 }
1355
1356 let negative_cases = vec![
1358 TypeSignature::Exact(vec![DataType::Utf8]),
1359 TypeSignature::Uniform(1, vec![DataType::Float64]),
1360 TypeSignature::Any(1),
1361 TypeSignature::VariadicAny,
1362 TypeSignature::OneOf(vec![
1363 TypeSignature::Exact(vec![DataType::Int8]),
1364 TypeSignature::Uniform(1, vec![DataType::Int8]),
1365 ]),
1366 ];
1367
1368 for case in negative_cases {
1369 assert!(
1370 !case.supports_zero_argument(),
1371 "Expected {case:?} not to support zero arguments"
1372 );
1373 }
1374 }
1375
1376 #[test]
1377 fn type_signature_partial_ord() {
1378 assert!(TypeSignature::UserDefined < TypeSignature::VariadicAny);
1380 assert!(TypeSignature::UserDefined < TypeSignature::Any(1));
1381
1382 assert!(
1383 TypeSignature::Uniform(1, vec![DataType::Null])
1384 < TypeSignature::Uniform(1, vec![DataType::Boolean])
1385 );
1386 assert!(
1387 TypeSignature::Uniform(1, vec![DataType::Null])
1388 < TypeSignature::Uniform(2, vec![DataType::Null])
1389 );
1390 assert!(
1391 TypeSignature::Uniform(usize::MAX, vec![DataType::Null])
1392 < TypeSignature::Exact(vec![DataType::Null])
1393 );
1394 }
1395
1396 #[test]
1397 fn test_get_possible_types() {
1398 let type_signature = TypeSignature::Exact(vec![DataType::Int32, DataType::Int64]);
1399 let possible_types = type_signature.get_example_types();
1400 assert_eq!(possible_types, vec![vec![DataType::Int32, DataType::Int64]]);
1401
1402 let type_signature = TypeSignature::OneOf(vec![
1403 TypeSignature::Exact(vec![DataType::Int32, DataType::Int64]),
1404 TypeSignature::Exact(vec![DataType::Float32, DataType::Float64]),
1405 ]);
1406 let possible_types = type_signature.get_example_types();
1407 assert_eq!(
1408 possible_types,
1409 vec![
1410 vec![DataType::Int32, DataType::Int64],
1411 vec![DataType::Float32, DataType::Float64]
1412 ]
1413 );
1414
1415 let type_signature = TypeSignature::OneOf(vec![
1416 TypeSignature::Exact(vec![DataType::Int32, DataType::Int64]),
1417 TypeSignature::Exact(vec![DataType::Float32, DataType::Float64]),
1418 TypeSignature::Exact(vec![DataType::Utf8]),
1419 ]);
1420 let possible_types = type_signature.get_example_types();
1421 assert_eq!(
1422 possible_types,
1423 vec![
1424 vec![DataType::Int32, DataType::Int64],
1425 vec![DataType::Float32, DataType::Float64],
1426 vec![DataType::Utf8]
1427 ]
1428 );
1429
1430 let type_signature =
1431 TypeSignature::Uniform(2, vec![DataType::Float32, DataType::Int64]);
1432 let possible_types = type_signature.get_example_types();
1433 assert_eq!(
1434 possible_types,
1435 vec![
1436 vec![DataType::Float32, DataType::Float32],
1437 vec![DataType::Int64, DataType::Int64]
1438 ]
1439 );
1440
1441 let type_signature = TypeSignature::Coercible(vec![
1442 Coercion::new_exact(TypeSignatureClass::Native(logical_string())),
1443 Coercion::new_exact(TypeSignatureClass::Native(logical_int64())),
1444 ]);
1445 let possible_types = type_signature.get_example_types();
1446 assert_eq!(
1447 possible_types,
1448 vec![
1449 vec![DataType::Utf8, DataType::Int64],
1450 vec![DataType::LargeUtf8, DataType::Int64],
1451 vec![DataType::Utf8View, DataType::Int64]
1452 ]
1453 );
1454
1455 let type_signature =
1456 TypeSignature::Variadic(vec![DataType::Int32, DataType::Int64]);
1457 let possible_types = type_signature.get_example_types();
1458 assert_eq!(
1459 possible_types,
1460 vec![vec![DataType::Int32], vec![DataType::Int64]]
1461 );
1462
1463 let type_signature = TypeSignature::Numeric(2);
1464 let possible_types = type_signature.get_example_types();
1465 assert_eq!(
1466 possible_types,
1467 vec![
1468 vec![DataType::Int8, DataType::Int8],
1469 vec![DataType::Int16, DataType::Int16],
1470 vec![DataType::Int32, DataType::Int32],
1471 vec![DataType::Int64, DataType::Int64],
1472 vec![DataType::UInt8, DataType::UInt8],
1473 vec![DataType::UInt16, DataType::UInt16],
1474 vec![DataType::UInt32, DataType::UInt32],
1475 vec![DataType::UInt64, DataType::UInt64],
1476 vec![DataType::Float32, DataType::Float32],
1477 vec![DataType::Float64, DataType::Float64]
1478 ]
1479 );
1480
1481 let type_signature = TypeSignature::String(2);
1482 let possible_types = type_signature.get_example_types();
1483 assert_eq!(
1484 possible_types,
1485 vec![
1486 vec![DataType::Utf8, DataType::Utf8],
1487 vec![DataType::LargeUtf8, DataType::LargeUtf8],
1488 vec![DataType::Utf8View, DataType::Utf8View]
1489 ]
1490 );
1491 }
1492
1493 #[test]
1494 fn test_signature_with_parameter_names() {
1495 let sig = Signature::exact(
1496 vec![DataType::Int32, DataType::Utf8],
1497 Volatility::Immutable,
1498 )
1499 .with_parameter_names(vec!["count".to_string(), "name".to_string()])
1500 .unwrap();
1501
1502 assert_eq!(
1503 sig.parameter_names,
1504 Some(vec!["count".to_string(), "name".to_string()])
1505 );
1506 assert_eq!(
1507 sig.type_signature,
1508 TypeSignature::Exact(vec![DataType::Int32, DataType::Utf8])
1509 );
1510 }
1511
1512 #[test]
1513 fn test_signature_parameter_names_wrong_count() {
1514 let result = Signature::exact(
1515 vec![DataType::Int32, DataType::Utf8],
1516 Volatility::Immutable,
1517 )
1518 .with_parameter_names(vec!["count".to_string()]); assert!(result.is_err());
1521 assert!(result
1522 .unwrap_err()
1523 .to_string()
1524 .contains("does not match signature arity"));
1525 }
1526
1527 #[test]
1528 fn test_signature_parameter_names_duplicate() {
1529 let result = Signature::exact(
1530 vec![DataType::Int32, DataType::Int32],
1531 Volatility::Immutable,
1532 )
1533 .with_parameter_names(vec!["count".to_string(), "count".to_string()]);
1534
1535 assert!(result.is_err());
1536 assert!(result
1537 .unwrap_err()
1538 .to_string()
1539 .contains("Duplicate parameter name"));
1540 }
1541
1542 #[test]
1543 fn test_signature_parameter_names_variadic() {
1544 let result = Signature::variadic(vec![DataType::Int32], Volatility::Immutable)
1545 .with_parameter_names(vec!["arg".to_string()]);
1546
1547 assert!(result.is_err());
1548 assert!(result
1549 .unwrap_err()
1550 .to_string()
1551 .contains("variable arity signature"));
1552 }
1553
1554 #[test]
1555 fn test_signature_without_parameter_names() {
1556 let sig = Signature::exact(
1557 vec![DataType::Int32, DataType::Utf8],
1558 Volatility::Immutable,
1559 );
1560
1561 assert_eq!(sig.parameter_names, None);
1562 }
1563
1564 #[test]
1565 fn test_signature_uniform_with_parameter_names() {
1566 let sig = Signature::uniform(3, vec![DataType::Float64], Volatility::Immutable)
1567 .with_parameter_names(vec!["x".to_string(), "y".to_string(), "z".to_string()])
1568 .unwrap();
1569
1570 assert_eq!(
1571 sig.parameter_names,
1572 Some(vec!["x".to_string(), "y".to_string(), "z".to_string()])
1573 );
1574 }
1575
1576 #[test]
1577 fn test_signature_numeric_with_parameter_names() {
1578 let sig = Signature::numeric(2, Volatility::Immutable)
1579 .with_parameter_names(vec!["a".to_string(), "b".to_string()])
1580 .unwrap();
1581
1582 assert_eq!(
1583 sig.parameter_names,
1584 Some(vec!["a".to_string(), "b".to_string()])
1585 );
1586 }
1587
1588 #[test]
1589 fn test_signature_nullary_with_empty_names() {
1590 let sig = Signature::nullary(Volatility::Immutable)
1591 .with_parameter_names(Vec::<String>::new())
1592 .unwrap();
1593
1594 assert_eq!(sig.parameter_names, Some(vec![]));
1595 }
1596
1597 #[test]
1598 fn test_to_string_repr_with_names_exact() {
1599 let sig = TypeSignature::Exact(vec![DataType::Int32, DataType::Utf8]);
1600
1601 assert_eq!(sig.to_string_repr_with_names(None), vec!["Int32, Utf8"]);
1602
1603 let names = vec!["id".to_string(), "name".to_string()];
1604 assert_eq!(
1605 sig.to_string_repr_with_names(Some(&names)),
1606 vec!["id: Int32, name: Utf8"]
1607 );
1608 }
1609
1610 #[test]
1611 fn test_to_string_repr_with_names_any() {
1612 let sig = TypeSignature::Any(3);
1613
1614 assert_eq!(sig.to_string_repr_with_names(None), vec!["Any, Any, Any"]);
1615
1616 let names = vec!["x".to_string(), "y".to_string(), "z".to_string()];
1617 assert_eq!(
1618 sig.to_string_repr_with_names(Some(&names)),
1619 vec!["x: Any, y: Any, z: Any"]
1620 );
1621 }
1622
1623 #[test]
1624 fn test_to_string_repr_with_names_one_of() {
1625 let sig =
1626 TypeSignature::OneOf(vec![TypeSignature::Any(2), TypeSignature::Any(3)]);
1627
1628 assert_eq!(
1629 sig.to_string_repr_with_names(None),
1630 vec!["Any, Any", "Any, Any, Any"]
1631 );
1632
1633 let names = vec![
1634 "str".to_string(),
1635 "start_pos".to_string(),
1636 "length".to_string(),
1637 ];
1638 assert_eq!(
1639 sig.to_string_repr_with_names(Some(&names)),
1640 vec![
1641 "str: Any, start_pos: Any",
1642 "str: Any, start_pos: Any, length: Any"
1643 ]
1644 );
1645 }
1646
1647 #[test]
1648 fn test_to_string_repr_with_names_partial() {
1649 let sig = TypeSignature::Exact(vec![DataType::Int32, DataType::Utf8]);
1651
1652 let names = vec!["a".to_string(), "b".to_string(), "c".to_string()];
1654 assert_eq!(
1655 sig.to_string_repr_with_names(Some(&names)),
1656 vec!["a: Int32, b: Utf8"]
1657 );
1658 }
1659
1660 #[test]
1661 fn test_to_string_repr_with_names_uniform() {
1662 let sig = TypeSignature::Uniform(2, vec![DataType::Float64]);
1663
1664 assert_eq!(
1665 sig.to_string_repr_with_names(None),
1666 vec!["Float64, Float64"]
1667 );
1668
1669 let names = vec!["x".to_string(), "y".to_string()];
1670 assert_eq!(
1671 sig.to_string_repr_with_names(Some(&names)),
1672 vec!["x: Float64, y: Float64"]
1673 );
1674 }
1675
1676 #[test]
1677 fn test_to_string_repr_with_names_coercible() {
1678 let sig = TypeSignature::Coercible(vec![
1679 Coercion::new_exact(TypeSignatureClass::Native(logical_int32())),
1680 Coercion::new_exact(TypeSignatureClass::Native(logical_int32())),
1681 ]);
1682
1683 let names = vec!["a".to_string(), "b".to_string()];
1684 let result = sig.to_string_repr_with_names(Some(&names));
1685 assert_eq!(result.len(), 1);
1687 assert!(result[0].starts_with("a: "));
1688 assert!(result[0].contains(", b: "));
1689 }
1690
1691 #[test]
1692 fn test_to_string_repr_with_names_comparable_numeric_string() {
1693 let comparable = TypeSignature::Comparable(3);
1694 let numeric = TypeSignature::Numeric(2);
1695 let string_sig = TypeSignature::String(2);
1696
1697 let names = vec!["a".to_string(), "b".to_string(), "c".to_string()];
1698
1699 assert_eq!(
1701 comparable.to_string_repr_with_names(Some(&names)),
1702 vec!["a: Comparable, b: Comparable, c: Comparable"]
1703 );
1704 assert_eq!(
1705 numeric.to_string_repr_with_names(Some(&names)),
1706 vec!["a: Numeric, b: Numeric"]
1707 );
1708 assert_eq!(
1709 string_sig.to_string_repr_with_names(Some(&names)),
1710 vec!["a: String, b: String"]
1711 );
1712 }
1713
1714 #[test]
1715 fn test_to_string_repr_with_names_variadic_fallback() {
1716 let variadic = TypeSignature::Variadic(vec![DataType::Utf8, DataType::LargeUtf8]);
1717 let names = vec!["x".to_string()];
1718 assert_eq!(
1719 variadic.to_string_repr_with_names(Some(&names)),
1720 variadic.to_string_repr()
1721 );
1722
1723 let variadic_any = TypeSignature::VariadicAny;
1724 assert_eq!(
1725 variadic_any.to_string_repr_with_names(Some(&names)),
1726 variadic_any.to_string_repr()
1727 );
1728
1729 let user_defined = TypeSignature::UserDefined;
1731 assert_eq!(
1732 user_defined.to_string_repr_with_names(Some(&names)),
1733 vec!["x"]
1734 );
1735 assert_eq!(
1736 user_defined.to_string_repr_with_names(None),
1737 user_defined.to_string_repr()
1738 );
1739 }
1740
1741 #[test]
1742 fn test_to_string_repr_with_names_nullary() {
1743 let sig = TypeSignature::Nullary;
1744 let names = vec!["x".to_string()];
1745
1746 assert_eq!(
1748 sig.to_string_repr_with_names(Some(&names)),
1749 vec!["NullAry()"]
1750 );
1751 assert_eq!(sig.to_string_repr_with_names(None), vec!["NullAry()"]);
1752 }
1753
1754 #[test]
1755 fn test_to_string_repr_with_names_array_signature() {
1756 let sig = TypeSignature::ArraySignature(ArrayFunctionSignature::Array {
1757 arguments: vec![
1758 ArrayFunctionArgument::Array,
1759 ArrayFunctionArgument::Index,
1760 ArrayFunctionArgument::Element,
1761 ],
1762 array_coercion: None,
1763 });
1764
1765 assert_eq!(
1766 sig.to_string_repr_with_names(None),
1767 vec!["array, index, element"]
1768 );
1769
1770 let names = vec!["arr".to_string(), "idx".to_string(), "val".to_string()];
1771 assert_eq!(
1772 sig.to_string_repr_with_names(Some(&names)),
1773 vec!["arr: array, idx: index, val: element"]
1774 );
1775
1776 let recursive =
1777 TypeSignature::ArraySignature(ArrayFunctionSignature::RecursiveArray);
1778 let names = vec!["array".to_string()];
1779 assert_eq!(
1780 recursive.to_string_repr_with_names(Some(&names)),
1781 vec!["array: recursive_array"]
1782 );
1783
1784 let map_array = TypeSignature::ArraySignature(ArrayFunctionSignature::MapArray);
1786 let names = vec!["map".to_string()];
1787 assert_eq!(
1788 map_array.to_string_repr_with_names(Some(&names)),
1789 vec!["map: map_array"]
1790 );
1791 }
1792
1793 #[test]
1794 fn test_type_signature_arity_exact() {
1795 let sig = TypeSignature::Exact(vec![DataType::Int32, DataType::Utf8]);
1796 assert_eq!(sig.arity(), Arity::Fixed(2));
1797
1798 let sig = TypeSignature::Exact(vec![]);
1799 assert_eq!(sig.arity(), Arity::Fixed(0));
1800 }
1801
1802 #[test]
1803 fn test_type_signature_arity_uniform() {
1804 let sig = TypeSignature::Uniform(3, vec![DataType::Float64]);
1805 assert_eq!(sig.arity(), Arity::Fixed(3));
1806
1807 let sig = TypeSignature::Uniform(1, vec![DataType::Int32]);
1808 assert_eq!(sig.arity(), Arity::Fixed(1));
1809 }
1810
1811 #[test]
1812 fn test_type_signature_arity_numeric() {
1813 let sig = TypeSignature::Numeric(2);
1814 assert_eq!(sig.arity(), Arity::Fixed(2));
1815 }
1816
1817 #[test]
1818 fn test_type_signature_arity_string() {
1819 let sig = TypeSignature::String(3);
1820 assert_eq!(sig.arity(), Arity::Fixed(3));
1821 }
1822
1823 #[test]
1824 fn test_type_signature_arity_comparable() {
1825 let sig = TypeSignature::Comparable(2);
1826 assert_eq!(sig.arity(), Arity::Fixed(2));
1827 }
1828
1829 #[test]
1830 fn test_type_signature_arity_any() {
1831 let sig = TypeSignature::Any(4);
1832 assert_eq!(sig.arity(), Arity::Fixed(4));
1833 }
1834
1835 #[test]
1836 fn test_type_signature_arity_coercible() {
1837 let sig = TypeSignature::Coercible(vec![
1838 Coercion::new_exact(TypeSignatureClass::Native(logical_int32())),
1839 Coercion::new_exact(TypeSignatureClass::Native(logical_string())),
1840 ]);
1841 assert_eq!(sig.arity(), Arity::Fixed(2));
1842 }
1843
1844 #[test]
1845 fn test_type_signature_arity_nullary() {
1846 let sig = TypeSignature::Nullary;
1847 assert_eq!(sig.arity(), Arity::Fixed(0));
1848 }
1849
1850 #[test]
1851 fn test_type_signature_arity_array_signature() {
1852 let sig = TypeSignature::ArraySignature(ArrayFunctionSignature::Array {
1854 arguments: vec![ArrayFunctionArgument::Array, ArrayFunctionArgument::Index],
1855 array_coercion: None,
1856 });
1857 assert_eq!(sig.arity(), Arity::Fixed(2));
1858
1859 let sig = TypeSignature::ArraySignature(ArrayFunctionSignature::Array {
1861 arguments: vec![
1862 ArrayFunctionArgument::Array,
1863 ArrayFunctionArgument::Element,
1864 ArrayFunctionArgument::Index,
1865 ],
1866 array_coercion: None,
1867 });
1868 assert_eq!(sig.arity(), Arity::Fixed(3));
1869
1870 let sig = TypeSignature::ArraySignature(ArrayFunctionSignature::RecursiveArray);
1872 assert_eq!(sig.arity(), Arity::Fixed(1));
1873
1874 let sig = TypeSignature::ArraySignature(ArrayFunctionSignature::MapArray);
1876 assert_eq!(sig.arity(), Arity::Fixed(1));
1877 }
1878
1879 #[test]
1880 fn test_type_signature_arity_one_of_fixed() {
1881 let sig = TypeSignature::OneOf(vec![
1883 TypeSignature::Exact(vec![DataType::Int32]),
1884 TypeSignature::Exact(vec![DataType::Int32, DataType::Utf8]),
1885 TypeSignature::Exact(vec![
1886 DataType::Int32,
1887 DataType::Utf8,
1888 DataType::Float64,
1889 ]),
1890 ]);
1891 assert_eq!(sig.arity(), Arity::Fixed(3));
1892 }
1893
1894 #[test]
1895 fn test_type_signature_arity_one_of_variable() {
1896 let sig = TypeSignature::OneOf(vec![
1898 TypeSignature::Exact(vec![DataType::Int32]),
1899 TypeSignature::VariadicAny,
1900 ]);
1901 assert_eq!(sig.arity(), Arity::Variable);
1902 }
1903
1904 #[test]
1905 fn test_type_signature_arity_variadic() {
1906 let sig = TypeSignature::Variadic(vec![DataType::Int32]);
1907 assert_eq!(sig.arity(), Arity::Variable);
1908
1909 let sig = TypeSignature::VariadicAny;
1910 assert_eq!(sig.arity(), Arity::Variable);
1911 }
1912
1913 #[test]
1914 fn test_type_signature_arity_user_defined() {
1915 let sig = TypeSignature::UserDefined;
1916 assert_eq!(sig.arity(), Arity::Variable);
1917 }
1918}