sdf-jkl opened a new issue, #11939:
URL: https://github.com/apache/arrow-rs/issues/11939

   ## Describe the bug
   
   `cast_to_variant_with_options` with `CastOptions { safe: true, .. }` encodes 
conversion failures as `Variant::Null` while leaving the output row valid. 
Arrow's cast kernel marks failed conversions null in the output array, as 
documented by 
[`CastOptions::safe`](https://github.com/apache/arrow-rs/blob/5746b443f70b4e55676be59cea317501a94ec810/arrow-cast/src/cast/mod.rs#L231-L235).
   
   Found while implementing Spark-compatible SQL `TRY_CAST(... AS VARIANT)` in 
[datafusion-variant](https://github.com/datafusion-contrib/datafusion-variant). 
[Spark documents `TRY_CAST` as returning SQL NULL on runtime conversion errors, 
including 
overflow](https://spark.apache.org/docs/latest/sql-ref-ansi-compliance.html#cast).
 Downstream code must currently convert these failed results to SQL NULL 
explicitly.
   
   ## To Reproduce
   
   Reproduced with `arrow = "60.0.0"` and `parquet-variant-compute = "60.0.0"`:
   
   ```rust
   use arrow::array::{Array, TimestampSecondArray};
   use arrow::compute::{CastOptions, cast_with_options};
   use arrow::datatypes::{DataType, TimeUnit};
   use parquet_variant_compute::cast_to_variant_with_options;
   
   fn main() {
       let input = TimestampSecondArray::from(vec![Some(i64::MAX), Some(0), 
None]);
       let options = CastOptions { safe: true, ..Default::default() };
   
       let arrow = cast_with_options(
           &input,
           &DataType::Timestamp(TimeUnit::Microsecond, None),
           &options,
       ).unwrap();
       let variant = cast_to_variant_with_options(&input, &options).unwrap();
   
       println!("Arrow overflow is null: {}", arrow.is_null(0));
       println!("Variant overflow is null: {}", variant.is_null(0));
       println!("Variant overflow value: {:?}", variant.value(0));
       assert!(!variant.is_null(1));
       assert!(variant.is_null(2));
       assert!(arrow.is_null(0));
       assert!(variant.is_null(0)); // Fails: overflow is encoded as 
Variant::Null.
   }
   ```
   
   Output before the assertion failure:
   
   ```text
   Arrow overflow is null: true
   Variant overflow is null: false
   Variant overflow value: Null
   ```
   
   ## Expected behavior
   
   For a failed top-level conversion with `safe: true`, mark the output row 
null, matching Arrow's cast kernel. Valid conversions and input nulls should 
retain their current behavior; `safe: false` should continue to return an error.
   
   ## Additional context
   
   Source inspection of `main` at `5746b443f7` confirms the same behavior: the 
[failure 
branch](https://github.com/apache/arrow-rs/blob/5746b443f70b4e55676be59cea317501a94ec810/parquet-variant-compute/src/arrow_to_variant.rs#L367-L372)
 appends `Variant::Null`, and the [timestamp overflow 
test](https://github.com/apache/arrow-rs/blob/5746b443f70b4e55676be59cea317501a94ec810/parquet-variant-compute/src/cast_to_variant.rs#L916-L934)
 expects it.
   
   The [original discussion in 
#8059](https://github.com/apache/arrow-rs/issues/8059#issuecomment-3167642459) 
proposed setting the array element null on overflow, following Arrow's cast 
model. A [later discussion in 
#8233](https://github.com/apache/arrow-rs/pull/8233#discussion_r2308739717) 
suggested `Variant::Null` instead of `None`. 
[#8984](https://github.com/apache/arrow-rs/pull/8984) subsequently unified the 
options with Arrow's `CastOptions` while preserving behavior.
   


-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to