1717
1818use std:: { collections:: HashMap , sync:: Arc } ;
1919
20+ use crate :: arrow_wrappers:: WrappedSchema ;
2021use abi_stable:: { std_types:: RVec , StableAbi } ;
2122use arrow:: {
2223 datatypes:: { DataType , Field , Schema , SchemaRef } ,
2324 error:: ArrowError ,
2425 ffi:: FFI_ArrowSchema ,
2526} ;
27+ use arrow_schema:: FieldRef ;
2628use datafusion:: {
2729 error:: { DataFusionError , Result } ,
2830 logical_expr:: function:: PartitionEvaluatorArgs ,
@@ -38,51 +40,52 @@ use datafusion_proto::{
3840} ;
3941use prost:: Message ;
4042
41- use crate :: arrow_wrappers:: WrappedSchema ;
42-
43+ /// A stable struct for sharing [`PartitionEvaluatorArgs`] across FFI boundaries.
44+ /// For an explanation of each field, see the corresponding function
45+ /// defined in [`PartitionEvaluatorArgs`].
4346#[ repr( C ) ]
4447#[ derive( Debug , StableAbi ) ]
4548#[ allow( non_camel_case_types) ]
4649pub struct FFI_PartitionEvaluatorArgs {
4750 input_exprs : RVec < RVec < u8 > > ,
48- input_types : RVec < WrappedSchema > ,
51+ input_fields : RVec < WrappedSchema > ,
4952 is_reversed : bool ,
5053 ignore_nulls : bool ,
5154 schema : WrappedSchema ,
5255}
5356
54-
5557impl TryFrom < PartitionEvaluatorArgs < ' _ > > for FFI_PartitionEvaluatorArgs {
56-
5758 type Error = DataFusionError ;
58- fn try_from (
59- args : PartitionEvaluatorArgs ,
60- ) -> Result < Self , DataFusionError > {
59+ fn try_from ( args : PartitionEvaluatorArgs ) -> Result < Self , DataFusionError > {
6160 // This is a bit of a hack. Since PartitionEvaluatorArgs does not carry a schema
6261 // around, and instead passes the data types directly we are unable to decode the
6362 // protobuf PhysicalExpr correctly. In evaluating the code the only place these
6463 // appear to be really used are the Column data types. So here we will find all
6564 // of the required columns and create a schema that has empty fields except for
6665 // the ones we require. Ideally we would enhance PartitionEvaluatorArgs to just
6766 // pass along the schema, but that is a larger breaking change.
68- let required_columns: HashMap < usize , ( & str , & DataType ) > = args. input_exprs ( ) . iter ( ) . zip ( args. input_types ( ) )
69- . filter_map ( |( expr, data_type) | {
70- expr. as_any ( ) . downcast_ref :: < Column > ( ) . map ( |column| ( column. index ( ) , ( column. name ( ) , data_type) ) )
67+ let required_columns: HashMap < usize , ( & str , & DataType ) > = args
68+ . input_exprs ( )
69+ . iter ( )
70+ . zip ( args. input_fields ( ) )
71+ . filter_map ( |( expr, field) | {
72+ expr. as_any ( )
73+ . downcast_ref :: < Column > ( )
74+ . map ( |column| ( column. index ( ) , ( column. name ( ) , field. data_type ( ) ) ) )
7175 } )
7276 . collect ( ) ;
7377
7478 let max_column = required_columns. keys ( ) . max ( ) . unwrap_or ( & 0 ) . to_owned ( ) ;
75- let fields: Vec < _ > = ( 0 ..max_column) . into_iter ( )
76- . map ( |idx| {
77- match required_columns. get ( & idx) {
78- Some ( ( name, data_type) ) => {
79- Field :: new ( * name, ( * data_type) . clone ( ) , true )
80- }
81- None => {
82- Field :: new ( format ! ( "ffi_partition_evaluator_col_{idx}" ) , DataType :: Null , true )
83- }
84- }
85- } ) . collect ( ) ;
79+ let fields: Vec < _ > = ( 0 ..max_column)
80+ . map ( |idx| match required_columns. get ( & idx) {
81+ Some ( ( name, data_type) ) => Field :: new ( * name, ( * data_type) . clone ( ) , true ) ,
82+ None => Field :: new (
83+ format ! ( "ffi_partition_evaluator_col_{idx}" ) ,
84+ DataType :: Null ,
85+ true ,
86+ ) ,
87+ } )
88+ . collect ( ) ;
8689 let schema = Arc :: new ( Schema :: new ( fields) ) ;
8790
8891 let codec = DefaultPhysicalExtensionCodec { } ;
@@ -91,8 +94,8 @@ impl TryFrom<PartitionEvaluatorArgs<'_>> for FFI_PartitionEvaluatorArgs {
9194 . map ( |expr_node| expr_node. encode_to_vec ( ) . into ( ) )
9295 . collect ( ) ;
9396
94- let input_types = args
95- . input_types ( )
97+ let input_fields = args
98+ . input_fields ( )
9699 . iter ( )
97100 . map ( |input_type| FFI_ArrowSchema :: try_from ( input_type) . map ( WrappedSchema ) )
98101 . collect :: < Result < Vec < _ > , ArrowError > > ( ) ?
@@ -102,7 +105,7 @@ impl TryFrom<PartitionEvaluatorArgs<'_>> for FFI_PartitionEvaluatorArgs {
102105
103106 Ok ( Self {
104107 input_exprs,
105- input_types ,
108+ input_fields ,
106109 schema,
107110 is_reversed : args. is_reversed ( ) ,
108111 ignore_nulls : args. ignore_nulls ( ) ,
@@ -116,7 +119,7 @@ impl TryFrom<PartitionEvaluatorArgs<'_>> for FFI_PartitionEvaluatorArgs {
116119/// PartitionEvaluatorArgs can then reference.
117120pub struct ForeignPartitionEvaluatorArgs {
118121 input_exprs : Vec < Arc < dyn PhysicalExpr > > ,
119- input_types : Vec < DataType > ,
122+ input_fields : Vec < FieldRef > ,
120123 is_reversed : bool ,
121124 ignore_nulls : bool ,
122125}
@@ -142,14 +145,14 @@ impl TryFrom<FFI_PartitionEvaluatorArgs> for ForeignPartitionEvaluatorArgs {
142145 } )
143146 . collect :: < Result < Vec < _ > > > ( ) ?;
144147
145- let input_types = input_exprs
148+ let input_fields = input_exprs
146149 . iter ( )
147- . map ( |expr| expr. data_type ( & schema) )
150+ . map ( |expr| expr. return_field ( & schema) )
148151 . collect :: < Result < Vec < _ > > > ( ) ?;
149152
150153 Ok ( Self {
151154 input_exprs,
152- input_types ,
155+ input_fields ,
153156 is_reversed : value. is_reversed ,
154157 ignore_nulls : value. ignore_nulls ,
155158 } )
@@ -160,7 +163,7 @@ impl<'a> From<&'a ForeignPartitionEvaluatorArgs> for PartitionEvaluatorArgs<'a>
160163 fn from ( value : & ' a ForeignPartitionEvaluatorArgs ) -> Self {
161164 PartitionEvaluatorArgs :: new (
162165 & value. input_exprs ,
163- & value. input_types ,
166+ & value. input_fields ,
164167 value. is_reversed ,
165168 value. ignore_nulls ,
166169 )
0 commit comments