@@ -26,9 +26,7 @@ use vortex::VortexSessionDefault;
2626use vortex:: array:: VortexSessionExecute ;
2727use vortex:: dtype:: DType ;
2828use vortex:: dtype:: Nullability ;
29- use vortex:: error:: VortexResult ;
3029use vortex:: expr:: Expression ;
31- use vortex:: expr:: and_collect;
3230use vortex:: expr:: byte_length;
3331use vortex:: expr:: cast;
3432use vortex:: expr:: get_item;
@@ -39,10 +37,8 @@ use vortex::expr::list_length;
3937use vortex:: expr:: lit;
4038use vortex:: expr:: nested_case_when;
4139use vortex:: expr:: not;
42- use vortex:: expr:: or_collect;
4340use vortex:: expr:: pack;
4441use vortex:: expr:: root;
45- use vortex:: scalar:: Scalar ;
4642use vortex:: scalar_fn:: ScalarFnVTableExt ;
4743use vortex:: scalar_fn:: fns:: binary:: Binary ;
4844use vortex:: scalar_fn:: fns:: like:: Like ;
@@ -440,64 +436,27 @@ impl DefaultExpressionConverter {
440436 return Err ( Unconverted :: Unsupported ) ;
441437 }
442438 let value_dtype = converted_dtype ( & value, input_dtype) ?;
443- let operator = if in_list. negated ( ) {
444- Operator :: NotEq
445- } else {
446- Operator :: Eq
447- } ;
448- // A positive list of literals becomes one set lookup. An OR of equalities would
449- // scan the needle once per element, which dynamic join filters make up to 150 times.
450- // Floats keep the comparisons, whose -0.0 and NaN semantics differ from set membership.
451- let is_float = matches ! ( & value_dtype, DType :: Primitive ( ptype, _) if ptype. is_float( ) ) ;
452- if !in_list. negated ( ) && !is_float {
453- let elements = in_list
454- . list ( )
455- . iter ( )
456- . map ( |element| self . convert_expr ( element, schema, input_dtype) )
457- . collect :: < Conversion < Vec < _ > > > ( ) ?;
458- let scalars = elements
459- . iter ( )
460- . map ( |element| element. as_opt :: < Literal > ( ) . cloned ( ) )
461- . collect :: < Option < Vec < _ > > > ( ) ;
462- // Null elements make a nullable list, whose SQL semantics `in_list` preserves.
463- let element_dtype = if scalars. iter ( ) . flatten ( ) . any ( Scalar :: is_null) {
464- value_dtype. as_nullable ( )
465- } else {
466- value_dtype. as_nonnullable ( )
467- } ;
468- if let Some ( scalars) = scalars
469- && !scalars. is_empty ( )
470- && scalars
471- . iter ( )
472- . all ( |scalar| scalar. dtype ( ) . eq_ignore_nullability ( & element_dtype) )
473- {
474- let scalars = scalars
475- . iter ( )
476- . map ( |scalar| scalar. cast ( & element_dtype) )
477- . collect :: < VortexResult < Vec < _ > > > ( )
478- . map_err ( |_| Unconverted :: Unsupported ) ?;
479- return Ok ( in_list_of ( value, element_dtype, scalars) ) ;
480- }
481- }
482- let mut comparisons = Vec :: with_capacity ( in_list. len ( ) ) ;
483- for element in in_list. list ( ) {
484- let element = self . convert_expr ( element, schema, input_dtype) ?;
485- let element_dtype = converted_dtype ( & element, input_dtype) ?;
486- if element_dtype == DType :: Null {
487- comparisons. push ( lit ( None :: < bool > ) ) ;
488- } else if value_dtype. eq_ignore_nullability ( & element_dtype) {
489- comparisons. push ( Binary . new_expr ( operator, [ value. clone ( ) , element] ) ) ;
490- } else {
491- return Err ( Unconverted :: Unsupported ) ;
492- }
493- }
494- // Kleene AND/OR preserve SQL IN/NOT IN nulls; list_contains does not.
495- let membership = if in_list. negated ( ) {
496- and_collect ( comparisons)
439+
440+ let elements = in_list
441+ . list ( )
442+ . iter ( )
443+ . map ( |element| {
444+ let element = self . convert_expr ( element, schema, input_dtype) ?;
445+ element
446+ . as_opt :: < Literal > ( )
447+ . cloned ( )
448+ . ok_or ( Unconverted :: Unsupported )
449+ } )
450+ . collect :: < Conversion < Vec < _ > > > ( ) ?;
451+
452+ // An element of another type than the value declines the pushdown: no implicit casts.
453+ let membership =
454+ in_list_of ( value, value_dtype, elements) . map_err ( |_| Unconverted :: Unsupported ) ?;
455+ Ok ( if in_list. negated ( ) {
456+ not ( membership)
497457 } else {
498- or_collect ( comparisons)
499- } ;
500- membership. ok_or ( Unconverted :: Unsupported )
458+ membership
459+ } )
501460 }
502461
503462 fn convert_scalar_function (
0 commit comments