22//!
33//!
44//! [DataFusion]: https://datafusion.apache.org/
5- use std:: { any:: Any , collections:: BTreeMap , ops:: DerefMut , sync:: Arc } ;
5+ use std:: { any:: Any , collections:: BTreeMap , hash :: Hash , ops:: DerefMut , sync:: Arc } ;
66
77use :: http:: HeaderName ;
88use arrow:: datatypes:: DataType ;
9- use datafusion_common:: { DataFusionError , Result as DataFusionResult , config :: ConfigOptions } ;
9+ use datafusion_common:: { DataFusionError , Result as DataFusionResult } ;
1010use datafusion_expr:: {
1111 ColumnarValue , ScalarFunctionArgs , ScalarUDFImpl , Signature , TypeSignature ,
1212 async_udf:: { AsyncScalarUDF , AsyncScalarUDFImpl } ,
1313} ;
1414use tokio:: { runtime:: Handle , sync:: Mutex } ;
15+ use uuid:: Uuid ;
1516use wasmtime:: {
1617 Engine , Store ,
1718 component:: { Component , ResourceAny } ,
@@ -322,6 +323,9 @@ pub struct WasmScalarUdf {
322323 /// [`ScalarUDFImpl::name`] is sync and requires us to return a reference.
323324 name : String ,
324325
326+ /// We treat every UDF as unique, but we need a proxy value to express that.
327+ id : Uuid ,
328+
325329 /// Signature of the UDF.
326330 ///
327331 /// This was pre-fetched during UDF generation because
@@ -458,6 +462,7 @@ impl WasmScalarUdf {
458462 bindings : Arc :: clone ( & bindings) ,
459463 resource,
460464 name,
465+ id : Uuid :: new_v4 ( ) ,
461466 signature,
462467 return_type,
463468 } ) ;
@@ -508,6 +513,7 @@ impl std::fmt::Debug for WasmScalarUdf {
508513 bindings : _,
509514 resource,
510515 name,
516+ id,
511517 signature,
512518 return_type,
513519 } = self ;
@@ -517,12 +523,27 @@ impl std::fmt::Debug for WasmScalarUdf {
517523 . field ( "bindings" , & "<BINDINGS>" )
518524 . field ( "resource" , resource)
519525 . field ( "name" , name)
526+ . field ( "id" , id)
520527 . field ( "signature" , signature)
521528 . field ( "return_type" , return_type)
522529 . finish ( )
523530 }
524531}
525532
533+ impl PartialEq < Self > for WasmScalarUdf {
534+ fn eq ( & self , other : & Self ) -> bool {
535+ self . id == other. id
536+ }
537+ }
538+
539+ impl Eq for WasmScalarUdf { }
540+
541+ impl Hash for WasmScalarUdf {
542+ fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
543+ self . id . hash ( state) ;
544+ }
545+ }
546+
526547impl ScalarUDFImpl for WasmScalarUdf {
527548 fn as_any ( & self ) -> & dyn Any {
528549 self
@@ -579,8 +600,7 @@ impl AsyncScalarUDFImpl for WasmScalarUdf {
579600 async fn invoke_async_with_args (
580601 & self ,
581602 args : ScalarFunctionArgs ,
582- _option : & ConfigOptions ,
583- ) -> DataFusionResult < arrow:: array:: ArrayRef > {
603+ ) -> DataFusionResult < ColumnarValue > {
584604 let args = args. try_into ( ) ?;
585605 let mut store_guard = self . store . lock ( ) . await ;
586606 let return_type = self
@@ -596,10 +616,6 @@ impl AsyncScalarUDFImpl for WasmScalarUdf {
596616
597617 drop ( store_guard) ;
598618
599- let columnar_value: ColumnarValue = return_type. try_into ( ) ?;
600- match columnar_value {
601- ColumnarValue :: Array ( v) => Ok ( v) ,
602- ColumnarValue :: Scalar ( v) => v. to_array_of_size ( args. number_rows as usize ) ,
603- }
619+ return_type. try_into ( )
604620 }
605621}
0 commit comments