goldmedal commented on code in PR #14440: URL: https://github.com/apache/datafusion/pull/14440#discussion_r1957108526
########## datafusion/expr-common/src/signature.rs: ########## @@ -466,6 +551,133 @@ fn get_data_types(native_type: &NativeType) -> Vec<DataType> { } } +#[derive(Debug, Clone, Eq, PartialOrd)] +pub enum Coercion { Review Comment: It would be great if add some doc for it and its variants. ########## datafusion/expr-common/src/signature.rs: ########## @@ -466,6 +551,133 @@ fn get_data_types(native_type: &NativeType) -> Vec<DataType> { } } +#[derive(Debug, Clone, Eq, PartialOrd)] +pub enum Coercion { + Exact { + desired_type: TypeSignatureClass, + }, + Implicit { + desired_type: TypeSignatureClass, + implicit_coercion: ImplicitCoercion, + }, +} + +impl Coercion { + pub fn new_exact(desired_type: TypeSignatureClass) -> Self { + Self::Exact { desired_type } + } + + /// Create a new coercion with implicit coercion rules. + /// + /// `allowed_source_types` defines the possible types that can be coerced to `desired_type`. + /// `default_casted_type` is the default type to be used for coercion if we cast from other types via `allowed_source_types`. + pub fn new_implicit( + desired_type: TypeSignatureClass, + allowed_source_types: Vec<TypeSignatureClass>, + default_casted_type: NativeType, + ) -> Self { + Self::Implicit { + desired_type, + implicit_coercion: ImplicitCoercion { + allowed_source_types, + default_casted_type, + }, + } + } + + pub fn allowed_source_types(&self) -> &[TypeSignatureClass] { + match self { + Coercion::Exact { .. } => &[], + Coercion::Implicit { + implicit_coercion, .. + } => implicit_coercion.allowed_source_types.as_slice(), + } + } + + pub fn default_casted_type(&self) -> Option<&NativeType> { + match self { + Coercion::Exact { .. } => None, + Coercion::Implicit { + implicit_coercion, .. + } => Some(&implicit_coercion.default_casted_type), + } + } + + pub fn desired_type(&self) -> &TypeSignatureClass { + match self { + Coercion::Exact { desired_type } => desired_type, + Coercion::Implicit { desired_type, .. } => desired_type, + } + } + + pub fn implicit_coercion(&self) -> Option<&ImplicitCoercion> { + match self { + Coercion::Exact { .. } => None, + Coercion::Implicit { + implicit_coercion, .. + } => Some(implicit_coercion), + } + } +} + +impl Display for Coercion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Coercion({}", self.desired_type())?; + if let Some(implicit_coercion) = self.implicit_coercion() { + write!(f, ", implicit_coercion={implicit_coercion}",) + } else { + write!(f, ")") + } + } +} + +impl PartialEq for Coercion { + fn eq(&self, other: &Self) -> bool { + self.desired_type() == other.desired_type() + && self.implicit_coercion() == other.implicit_coercion() + } +} + +impl Hash for Coercion { + fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + self.desired_type().hash(state); + self.implicit_coercion().hash(state); + } +} + +#[derive(Debug, Clone, Eq, PartialOrd)] +pub struct ImplicitCoercion { Review Comment: We could also add some doc for it. Maybe adding some examples here is good. I was confused about what it be used for before I did some tests. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org For additional commands, e-mail: github-h...@datafusion.apache.org