This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-22592-c7f35d6f0595662d684a1c7eb64d8bb5599aeeee in repository https://gitbox.apache.org/repos/asf/datafusion.git
commit eedae1154bf2745ea6d025f3e55901db1d8b7fb7 Author: Andrew Lamb <[email protected]> AuthorDate: Thu May 28 14:48:27 2026 -0400 docs: clarify difference between try_cast_literal_to_type and ScalarValue::cast_to (#22592) ## Which issue does this PR close? - Part of #22577 (consolidate `ScalarValue` cast implementations). ## Rationale for this change I have been confused about the difference between `ScalarValue::cast_to` and `try_cast_literal_to_type` -- so after some research I would like to make the difference clearer ## What changes are included in this PR? Document on each function how it differs from the other, so the choice is obvious from the docs alone. ## Are these changes tested? by CI ## Are there any user-facing changes? Doc comments only. No code or API changes. Partially 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> --- datafusion/common/src/scalar/mod.rs | 23 +++++++++++++++++++++-- datafusion/expr-common/src/casts.rs | 26 +++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/datafusion/common/src/scalar/mod.rs b/datafusion/common/src/scalar/mod.rs index 1a98547785..73088dd942 100644 --- a/datafusion/common/src/scalar/mod.rs +++ b/datafusion/common/src/scalar/mod.rs @@ -4212,12 +4212,31 @@ impl ScalarValue { Some(v.as_ref().map(|v| v.as_str())) } - /// Try to cast this value to a ScalarValue of type `data_type` + /// Cast this value to a `ScalarValue` of type `target_type` using the + /// default [`CastOptions`]. + /// + /// This is a general-purpose cast with the same semantics as the Arrow + /// [`cast_with_options`] kernel and can therefore **lose information** -- + /// for example casting the floating point value `123.45` to the integer + /// `123`. + /// + /// Returns an error for casts the Arrow kernel cannot perform. + /// + /// # See Also + /// - [`try_cast_literal_to_type`]: for a *value-preserving* cast + /// + /// [`try_cast_literal_to_type`]: https://docs.rs/datafusion/latest/datafusion/logical_expr_common/casts/fn.try_cast_literal_to_type.html pub fn cast_to(&self, target_type: &DataType) -> Result<Self> { self.cast_to_with_options(target_type, &DEFAULT_CAST_OPTIONS) } - /// Try to cast this value to a ScalarValue of type `data_type` with [`CastOptions`] + /// Cast this value to type `target_type` with the given [`CastOptions`]. + /// + /// # See Also + /// - [`ScalarValue::cast_to`] for more details. + /// - [`try_cast_literal_to_type`]: for a *value-preserving* cast + /// + /// [`try_cast_literal_to_type`]: https://docs.rs/datafusion/latest/datafusion/logical_expr_common/casts/fn.try_cast_literal_to_type.html pub fn cast_to_with_options( &self, target_type: &DataType, diff --git a/datafusion/expr-common/src/casts.rs b/datafusion/expr-common/src/casts.rs index dad589e4bf..d18c3d4f04 100644 --- a/datafusion/expr-common/src/casts.rs +++ b/datafusion/expr-common/src/casts.rs @@ -31,7 +31,31 @@ use arrow::datatypes::{ use arrow::temporal_conversions::{MICROSECONDS, MILLISECONDS, NANOSECONDS}; use datafusion_common::ScalarValue; -/// Convert a literal value from one data type to another +/// Convert a literal [`ScalarValue`] to `target_type`, preserving the exact value. +/// +/// Returns `None` if the value cannot be represented in `target_type` +/// *exactly*. +/// +/// This is a restricted, value-preserving cast used to rewrite comparison +/// predicates of the form `CAST(col AS target_type) <op> literal` into +/// `col <op> try_cast_literal_to_type(literal, col_type)`. That rewrite is +/// only valid when the cast cannot change the comparison result. +/// +/// # Supported Casts +/// * numeric → numeric, including integers, decimals, `Date32`/`Date64` and +/// `Timestamp`s, rejecting values outside the target's range or that would +/// lose decimal digits +/// * string → string between `Utf8`, `LargeUtf8` and `Utf8View` +/// * wrapping a value into, or unwrapping it out of, a `Dictionary` whose value +/// type matches the literal's type +/// * `Binary` → `FixedSizeBinary` of the matching length +/// * `Timestamp` → `Timestamp` cast between different time units is allowed even +/// though it can truncate (for example nanoseconds → seconds), and a unit +/// conversion that overflows yields a `NULL` literal rather than `None`. +/// +/// # See Also +/// - [`ScalarValue::cast_to`]: a general-purpose cast that can lose information +/// or change a value's meaning. pub fn try_cast_literal_to_type( lit_value: &ScalarValue, target_type: &DataType, --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
