diff --git a/datafusion/common/src/metadata.rs b/datafusion/common/src/metadata.rs index ec0b3bc81467..39065808efb9 100644 --- a/datafusion/common/src/metadata.rs +++ b/datafusion/common/src/metadata.rs @@ -60,7 +60,15 @@ impl ScalarAndMetadata { target_type: &DataType, ) -> Result { let new_value = self.value().cast_to(target_type)?; - Ok(ScalarAndMetadata::new(new_value, self.metadata.clone())) + Ok(Self::new(new_value, self.metadata.clone())) + } +} + +/// create a new ScalarAndMetadata from a ScalarValue without +/// any metadata +impl From for ScalarAndMetadata { + fn from(value: ScalarValue) -> Self { + Self::new(value, None) } } diff --git a/datafusion/common/src/param_value.rs b/datafusion/common/src/param_value.rs index 5ab58239e66c..ebf68e4dd210 100644 --- a/datafusion/common/src/param_value.rs +++ b/datafusion/common/src/param_value.rs @@ -115,12 +115,7 @@ impl ParamValues { impl From> for ParamValues { fn from(value: Vec) -> Self { - Self::List( - value - .into_iter() - .map(|v| ScalarAndMetadata::new(v, None)) - .collect(), - ) + Self::List(value.into_iter().map(ScalarAndMetadata::from).collect()) } } @@ -131,7 +126,7 @@ where fn from(value: Vec<(K, ScalarValue)>) -> Self { let value: HashMap = value .into_iter() - .map(|(k, v)| (k.into(), ScalarAndMetadata::new(v, None))) + .map(|(k, v)| (k.into(), ScalarAndMetadata::from(v))) .collect(); Self::Map(value) } @@ -144,7 +139,7 @@ where fn from(value: HashMap) -> Self { let value: HashMap = value .into_iter() - .map(|(k, v)| (k.into(), ScalarAndMetadata::new(v, None))) + .map(|(k, v)| (k.into(), ScalarAndMetadata::from(v))) .collect(); Self::Map(value) } diff --git a/datafusion/expr/src/expr.rs b/datafusion/expr/src/expr.rs index e1115b714053..6077b3c1e5bb 100644 --- a/datafusion/expr/src/expr.rs +++ b/datafusion/expr/src/expr.rs @@ -47,6 +47,7 @@ use sqlparser::ast::{ // Moved in 51.0.0 to datafusion_common pub use datafusion_common::metadata::FieldMetadata; +use datafusion_common::metadata::ScalarAndMetadata; // This mirrors sqlparser::ast::NullTreatment but we need our own variant // for when the sql feature is disabled. @@ -424,6 +425,14 @@ impl From for Expr { } } +/// Create an [`Expr`] from an [`ScalarAndMetadata`] +impl From for Expr { + fn from(value: ScalarAndMetadata) -> Self { + let (value, metadata) = value.into_inner(); + Expr::Literal(value, metadata) + } +} + /// Create an [`Expr`] from an optional qualifier and a [`FieldRef`]. This is /// useful for creating [`Expr`] from a [`DFSchema`]. /// diff --git a/datafusion/sql/tests/cases/params.rs b/datafusion/sql/tests/cases/params.rs index e1075da5f999..4a484b1171bc 100644 --- a/datafusion/sql/tests/cases/params.rs +++ b/datafusion/sql/tests/cases/params.rs @@ -754,7 +754,7 @@ fn test_update_infer_with_metadata() { ("$2", Some(uuid_field.clone().with_name("id").into())), ]; let param_values = vec![ - ScalarAndMetadata::new(ScalarValue::from("Turing"), None), + ScalarAndMetadata::from(ScalarValue::from("Turing")), ScalarAndMetadata::new( ScalarValue::FixedSizeBinary(16, Some(uuid_bytes)), Some(uuid_field.metadata().into()), @@ -831,8 +831,8 @@ fn test_insert_infer_with_metadata() { ScalarValue::FixedSizeBinary(16, Some(uuid_bytes)), Some(uuid_field.metadata().into()), ), - ScalarAndMetadata::new(ScalarValue::from("Alan"), None), - ScalarAndMetadata::new(ScalarValue::from("Turing"), None), + ScalarAndMetadata::from(ScalarValue::from("Alan")), + ScalarAndMetadata::from(ScalarValue::from("Turing")), ]; // Check a normal insert