@@ -34,7 +34,7 @@ use arrow_string::like::starts_with;
3434use fnv:: FnvHashSet ;
3535use parquet:: schema:: types:: SchemaDescriptor ;
3636
37- use crate :: arrow:: get_arrow_datum;
37+ use crate :: arrow:: { get_arrow_datum, type_to_arrow_type } ;
3838use crate :: error:: { Result , invalid_data} ;
3939use crate :: expr:: visitors:: bound_predicate_visitor:: BoundPredicateVisitor ;
4040use crate :: expr:: { BoundPredicate , BoundReference } ;
@@ -278,6 +278,22 @@ fn project_column(
278278 }
279279}
280280
281+ /// Like `project_column`, but casts a numeric column the file stores in another type to
282+ /// `target_type`, as `RecordBatchTransformer` does. Narrowing the literal to the file type
283+ /// instead can turn it into null or round it.
284+ fn project_promoted_column (
285+ batch : & RecordBatch ,
286+ column_idx : usize ,
287+ target_type : & DataType ,
288+ ) -> std:: result:: Result < ArrayRef , ArrowError > {
289+ let column = project_column ( batch, column_idx) ?;
290+ if column. data_type ( ) . is_numeric ( ) && column. data_type ( ) != target_type {
291+ cast ( & column, target_type)
292+ } else {
293+ Ok ( column)
294+ }
295+ }
296+
281297fn compute_is_nan ( array : & ArrayRef ) -> std:: result:: Result < BooleanArray , ArrowError > {
282298 // Compute NaN over the contiguous values slice, then fold the null bitmap
283299 // in with a single bitwise AND so that null slots become false.
@@ -425,9 +441,10 @@ impl BoundPredicateVisitor for PredicateConverter<'_> {
425441 ) -> Result < Box < PredicateResult > > {
426442 if let Some ( idx) = self . bound_reference ( reference) ? {
427443 let literal = get_arrow_datum ( literal) ?;
444+ let target_type = type_to_arrow_type ( & reference. field ( ) . field_type ) ?;
428445
429446 Ok ( Box :: new ( move |batch| {
430- let left = project_column ( & batch, idx) ?;
447+ let left = project_promoted_column ( & batch, idx, & target_type ) ?;
431448 let literal = try_cast_literal ( & literal, left. data_type ( ) ) ?;
432449 lt ( & left, literal. as_ref ( ) )
433450 } ) )
@@ -445,9 +462,10 @@ impl BoundPredicateVisitor for PredicateConverter<'_> {
445462 ) -> Result < Box < PredicateResult > > {
446463 if let Some ( idx) = self . bound_reference ( reference) ? {
447464 let literal = get_arrow_datum ( literal) ?;
465+ let target_type = type_to_arrow_type ( & reference. field ( ) . field_type ) ?;
448466
449467 Ok ( Box :: new ( move |batch| {
450- let left = project_column ( & batch, idx) ?;
468+ let left = project_promoted_column ( & batch, idx, & target_type ) ?;
451469 let literal = try_cast_literal ( & literal, left. data_type ( ) ) ?;
452470 lt_eq ( & left, literal. as_ref ( ) )
453471 } ) )
@@ -465,9 +483,10 @@ impl BoundPredicateVisitor for PredicateConverter<'_> {
465483 ) -> Result < Box < PredicateResult > > {
466484 if let Some ( idx) = self . bound_reference ( reference) ? {
467485 let literal = get_arrow_datum ( literal) ?;
486+ let target_type = type_to_arrow_type ( & reference. field ( ) . field_type ) ?;
468487
469488 Ok ( Box :: new ( move |batch| {
470- let left = project_column ( & batch, idx) ?;
489+ let left = project_promoted_column ( & batch, idx, & target_type ) ?;
471490 let literal = try_cast_literal ( & literal, left. data_type ( ) ) ?;
472491 gt ( & left, literal. as_ref ( ) )
473492 } ) )
@@ -485,9 +504,10 @@ impl BoundPredicateVisitor for PredicateConverter<'_> {
485504 ) -> Result < Box < PredicateResult > > {
486505 if let Some ( idx) = self . bound_reference ( reference) ? {
487506 let literal = get_arrow_datum ( literal) ?;
507+ let target_type = type_to_arrow_type ( & reference. field ( ) . field_type ) ?;
488508
489509 Ok ( Box :: new ( move |batch| {
490- let left = project_column ( & batch, idx) ?;
510+ let left = project_promoted_column ( & batch, idx, & target_type ) ?;
491511 let literal = try_cast_literal ( & literal, left. data_type ( ) ) ?;
492512 gt_eq ( & left, literal. as_ref ( ) )
493513 } ) )
@@ -505,9 +525,10 @@ impl BoundPredicateVisitor for PredicateConverter<'_> {
505525 ) -> Result < Box < PredicateResult > > {
506526 if let Some ( idx) = self . bound_reference ( reference) ? {
507527 let literal = get_arrow_datum ( literal) ?;
528+ let target_type = type_to_arrow_type ( & reference. field ( ) . field_type ) ?;
508529
509530 Ok ( Box :: new ( move |batch| {
510- let left = project_column ( & batch, idx) ?;
531+ let left = project_promoted_column ( & batch, idx, & target_type ) ?;
511532 let literal = try_cast_literal ( & literal, left. data_type ( ) ) ?;
512533 eq ( & left, literal. as_ref ( ) )
513534 } ) )
@@ -525,9 +546,10 @@ impl BoundPredicateVisitor for PredicateConverter<'_> {
525546 ) -> Result < Box < PredicateResult > > {
526547 if let Some ( idx) = self . bound_reference ( reference) ? {
527548 let literal = get_arrow_datum ( literal) ?;
549+ let target_type = type_to_arrow_type ( & reference. field ( ) . field_type ) ?;
528550
529551 Ok ( Box :: new ( move |batch| {
530- let left = project_column ( & batch, idx) ?;
552+ let left = project_promoted_column ( & batch, idx, & target_type ) ?;
531553 let literal = try_cast_literal ( & literal, left. data_type ( ) ) ?;
532554 neq ( & left, literal. as_ref ( ) )
533555 } ) )
@@ -589,10 +611,11 @@ impl BoundPredicateVisitor for PredicateConverter<'_> {
589611 . iter ( )
590612 . map ( |lit| get_arrow_datum ( lit) . unwrap ( ) )
591613 . collect ( ) ;
614+ let target_type = type_to_arrow_type ( & reference. field ( ) . field_type ) ?;
592615
593616 Ok ( Box :: new ( move |batch| {
594617 // update this if arrow ever adds a native is_in kernel
595- let left = project_column ( & batch, idx) ?;
618+ let left = project_promoted_column ( & batch, idx, & target_type ) ?;
596619
597620 let mut acc = constant_bool_array ( false , batch. num_rows ( ) ) ;
598621 for literal in & literals {
@@ -619,10 +642,11 @@ impl BoundPredicateVisitor for PredicateConverter<'_> {
619642 . iter ( )
620643 . map ( |lit| get_arrow_datum ( lit) . unwrap ( ) )
621644 . collect ( ) ;
645+ let target_type = type_to_arrow_type ( & reference. field ( ) . field_type ) ?;
622646
623647 Ok ( Box :: new ( move |batch| {
624648 // update this if arrow ever adds a native not_in kernel
625- let left = project_column ( & batch, idx) ?;
649+ let left = project_promoted_column ( & batch, idx, & target_type ) ?;
626650 let mut acc = constant_bool_array ( true , batch. num_rows ( ) ) ;
627651 for literal in & literals {
628652 let literal = try_cast_literal ( literal, left. data_type ( ) ) ?;
0 commit comments