@@ -190,7 +190,7 @@ impl SedonaScalarKernel for RsSetCrs {
190190/// null will have the entire raster nulled out (not just the CRS column).
191191fn replace_raster_crs (
192192 raster_arg : & ColumnarValue ,
193- crs_value : & ColumnarValue ,
193+ crs_array : & StringViewArray ,
194194 input_nulls : Option < & NullBuffer > ,
195195) -> Result < ColumnarValue > {
196196 match raster_arg {
@@ -205,10 +205,8 @@ fn replace_raster_crs(
205205 } ) ?;
206206
207207 let num_rows = raster_struct. len ( ) ;
208- let new_crs_array = crs_value
209- . cast_to ( & DataType :: Utf8View , None ) ?
210- . to_array ( num_rows) ?;
211- let new_struct = swap_crs_column ( raster_struct, new_crs_array) ?;
208+ let new_crs: ArrayRef = broadcast_string_view ( crs_array, num_rows) ;
209+ let new_struct = swap_crs_column ( raster_struct, new_crs) ?;
212210
213211 // Merge input nulls: rows where the SRID/CRS input was null become null rasters
214212 let merged_nulls = NullBuffer :: union ( new_struct. nulls ( ) , input_nulls) ;
@@ -221,11 +219,8 @@ fn replace_raster_crs(
221219 Ok ( ColumnarValue :: Array ( Arc :: new ( new_struct) ) )
222220 }
223221 ColumnarValue :: Scalar ( ScalarValue :: Struct ( arc_struct) ) => {
224- let num_rows = arc_struct. len ( ) ;
225- let new_crs_array = crs_value
226- . cast_to ( & DataType :: Utf8View , None ) ?
227- . to_array ( num_rows) ?;
228- let new_struct = swap_crs_column ( arc_struct. as_ref ( ) , new_crs_array) ?;
222+ let new_crs: ArrayRef = Arc :: new ( crs_array. clone ( ) ) ;
223+ let new_struct = swap_crs_column ( arc_struct. as_ref ( ) , new_crs) ?;
229224
230225 // Merge input nulls: null SRID/CRS input produces a null raster
231226 let merged_nulls = NullBuffer :: union ( new_struct. nulls ( ) , input_nulls) ;
@@ -244,6 +239,23 @@ fn replace_raster_crs(
244239 }
245240}
246241
242+ /// Broadcast a `StringViewArray` to a target length.
243+ ///
244+ /// If the array already has the target length, it is returned as-is (clone of Arc).
245+ /// Otherwise the array must have length 1, and its single value is repeated.
246+ fn broadcast_string_view ( array : & StringViewArray , len : usize ) -> ArrayRef {
247+ if array. len ( ) == len {
248+ return Arc :: new ( array. clone ( ) ) ;
249+ }
250+ debug_assert_eq ! ( array. len( ) , 1 ) ;
251+ if array. is_null ( 0 ) {
252+ Arc :: new ( StringViewArray :: new_null ( len) )
253+ } else {
254+ let value = array. value ( 0 ) ;
255+ Arc :: new ( std:: iter:: repeat_n ( Some ( value) , len) . collect :: < StringViewArray > ( ) )
256+ }
257+ }
258+
247259/// Swap only the CRS column of a raster StructArray, keeping all other columns intact.
248260fn swap_crs_column ( raster_struct : & StructArray , new_crs_array : ArrayRef ) -> Result < StructArray > {
249261 let mut columns: Vec < ArrayRef > = raster_struct. columns ( ) . to_vec ( ) ;
@@ -291,7 +303,7 @@ fn extract_input_nulls(input: &ColumnarValue) -> Option<NullBuffer> {
291303fn srid_to_crs_columnar (
292304 srid_arg : & ColumnarValue ,
293305 maybe_engine : Option < & Arc < dyn CrsEngine + Send + Sync > > ,
294- ) -> Result < ColumnarValue > {
306+ ) -> Result < StringViewArray > {
295307 let mut srid_to_crs = CachedSRIDToCrs :: new ( ) ;
296308
297309 // Cast to Int64 for uniform handling
@@ -314,17 +326,7 @@ fn srid_to_crs_columnar(
314326 } )
315327 . collect :: < Result < _ > > ( ) ?;
316328
317- // Return as Scalar if the original was scalar, Array otherwise
318- if matches ! ( srid_arg, ColumnarValue :: Scalar ( _) ) {
319- let scalar = if crs_array. is_null ( 0 ) {
320- ScalarValue :: Utf8View ( None )
321- } else {
322- ScalarValue :: Utf8View ( Some ( crs_array. value ( 0 ) . to_string ( ) ) )
323- } ;
324- Ok ( ColumnarValue :: Scalar ( scalar) )
325- } else {
326- Ok ( ColumnarValue :: Array ( Arc :: new ( crs_array) ) )
327- }
329+ Ok ( crs_array)
328330}
329331
330332// ---------------------------------------------------------------------------
@@ -339,7 +341,7 @@ fn srid_to_crs_columnar(
339341fn normalize_crs_columnar (
340342 crs_arg : & ColumnarValue ,
341343 _maybe_engine : Option < & Arc < dyn CrsEngine + Send + Sync > > ,
342- ) -> Result < ColumnarValue > {
344+ ) -> Result < StringViewArray > {
343345 let mut crs_norm = CachedCrsNormalization :: new ( ) ;
344346
345347 let string_value = crs_arg. cast_to ( & DataType :: Utf8View , None ) ?;
@@ -358,17 +360,7 @@ fn normalize_crs_columnar(
358360 } )
359361 . collect :: < Result < _ > > ( ) ?;
360362
361- // Return as Scalar if the original was scalar, Array otherwise
362- if matches ! ( crs_arg, ColumnarValue :: Scalar ( _) ) {
363- let scalar = if crs_array. is_null ( 0 ) {
364- ScalarValue :: Utf8View ( None )
365- } else {
366- ScalarValue :: Utf8View ( Some ( crs_array. value ( 0 ) . to_string ( ) ) )
367- } ;
368- Ok ( ColumnarValue :: Scalar ( scalar) )
369- } else {
370- Ok ( ColumnarValue :: Array ( Arc :: new ( crs_array) ) )
371- }
363+ Ok ( crs_array)
372364}
373365
374366/// Validate a CRS string
0 commit comments