22// SPDX-FileCopyrightText: Copyright the Vortex contributors
33
44use std:: fmt:: Formatter ;
5+ use std:: ops:: BitOr ;
56
67use vortex_dtype:: DType ;
78use vortex_error:: VortexResult ;
89use vortex_error:: vortex_bail;
10+ use vortex_vector:: Datum ;
911
1012use crate :: ArrayRef ;
1113use crate :: compute:: list_contains as compute_list_contains;
14+ use crate :: expr:: Arity ;
1215use crate :: expr:: ChildName ;
16+ use crate :: expr:: ExecutionArgs ;
1317use crate :: expr:: ExprId ;
1418use crate :: expr:: Expression ;
15- use crate :: expr:: ExpressionView ;
1619use crate :: expr:: StatsCatalog ;
1720use crate :: expr:: VTable ;
1821use crate :: expr:: VTableExt ;
@@ -22,11 +25,12 @@ use crate::expr::exprs::binary::lt;
2225use crate :: expr:: exprs:: binary:: or;
2326use crate :: expr:: exprs:: literal:: Literal ;
2427use crate :: expr:: exprs:: literal:: lit;
28+ use crate :: expr:: functions:: EmptyOptions ;
2529
2630pub struct ListContains ;
2731
2832impl VTable for ListContains {
29- type Options = ( ) ;
33+ type Options = EmptyOptions ;
3034
3135 fn id ( & self ) -> ExprId {
3236 ExprId :: from ( "vortex.list.contains" )
@@ -36,18 +40,12 @@ impl VTable for ListContains {
3640 Ok ( Some ( vec ! [ ] ) )
3741 }
3842
39- fn deserialize ( & self , _metadata : & [ u8 ] ) -> VortexResult < Option < Self :: Options > > {
40- Ok ( Some ( ( ) ) )
43+ fn deserialize ( & self , _metadata : & [ u8 ] ) -> VortexResult < Self :: Options > {
44+ Ok ( EmptyOptions )
4145 }
4246
43- fn validate ( & self , expr : & ExpressionView < Self > ) -> VortexResult < ( ) > {
44- if expr. children ( ) . len ( ) != 2 {
45- vortex_bail ! (
46- "ListContains expression requires exactly 2 children, got {}" ,
47- expr. children( ) . len( )
48- ) ;
49- }
50- Ok ( ( ) )
47+ fn arity ( & self , _options : & Self :: Options ) -> Arity {
48+ Arity :: Exact ( 2 )
5149 }
5250
5351 fn child_name ( & self , _instance : & Self :: Options , child_idx : usize ) -> ChildName {
@@ -60,18 +58,22 @@ impl VTable for ListContains {
6058 ) ,
6159 }
6260 }
63-
64- fn fmt_sql ( & self , expr : & ExpressionView < Self > , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
61+ fn fmt_sql (
62+ & self ,
63+ _options : & Self :: Options ,
64+ expr : & Expression ,
65+ f : & mut Formatter < ' _ > ,
66+ ) -> std:: fmt:: Result {
6567 write ! ( f, "contains(" ) ?;
6668 expr. child ( 0 ) . fmt_sql ( f) ?;
6769 write ! ( f, ", " ) ?;
6870 expr. child ( 1 ) . fmt_sql ( f) ?;
6971 write ! ( f, ")" )
7072 }
7173
72- fn return_dtype ( & self , expr : & ExpressionView < Self > , scope : & DType ) -> VortexResult < DType > {
73- let list_dtype = expr . child ( 0 ) . return_dtype ( scope ) ? ;
74- let value_dtype = expr . child ( 1 ) . return_dtype ( scope ) ? ;
74+ fn return_dtype ( & self , _options : & Self :: Options , arg_dtypes : & [ DType ] ) -> VortexResult < DType > {
75+ let list_dtype = & arg_dtypes [ 0 ] ;
76+ let needle_dtype = & arg_dtypes [ 0 ] ;
7577
7678 let nullability = match list_dtype {
7779 DType :: List ( _, list_nullability) => list_nullability,
@@ -81,38 +83,52 @@ impl VTable for ListContains {
8183 list_dtype
8284 ) ;
8385 }
84- } | value_dtype. nullability ( ) ;
86+ }
87+ . bitor ( needle_dtype. nullability ( ) ) ;
8588
8689 Ok ( DType :: Bool ( nullability) )
8790 }
8891
89- fn evaluate ( & self , expr : & ExpressionView < Self > , scope : & ArrayRef ) -> VortexResult < ArrayRef > {
92+ fn evaluate (
93+ & self ,
94+ _options : & Self :: Options ,
95+ expr : & Expression ,
96+ scope : & ArrayRef ,
97+ ) -> VortexResult < ArrayRef > {
9098 let list_array = expr. child ( 0 ) . evaluate ( scope) ?;
9199 let value_array = expr. child ( 1 ) . evaluate ( scope) ?;
92100 compute_list_contains ( list_array. as_ref ( ) , value_array. as_ref ( ) )
93101 }
94102
103+ fn execute ( & self , _data : & Self :: Options , _args : ExecutionArgs ) -> VortexResult < Datum > {
104+ todo ! ( )
105+ }
106+
95107 fn stat_falsification (
96108 & self ,
97- expr : & ExpressionView < Self > ,
109+ _options : & Self :: Options ,
110+ expr : & Expression ,
98111 catalog : & dyn StatsCatalog ,
99112 ) -> Option < Expression > {
113+ let list = expr. child ( 0 ) ;
114+ let needle = expr. child ( 1 ) ;
115+
100116 // falsification(contains([1,2,5], x)) =>
101117 // falsification(x != 1) and falsification(x != 2) and falsification(x != 5)
102- let min = expr . list ( ) . stat_min ( catalog) ?;
103- let max = expr . list ( ) . stat_max ( catalog) ?;
118+ let min = list. stat_min ( catalog) ?;
119+ let max = list. stat_max ( catalog) ?;
104120 // If the list is constant when we can compare each element to the value
105121 if min == max {
106122 let list_ = min
107123 . as_opt :: < Literal > ( )
108- . and_then ( |l| l. data ( ) . as_list_opt ( ) )
124+ . and_then ( |l| l. as_list_opt ( ) )
109125 . and_then ( |l| l. elements ( ) ) ?;
110126 if list_. is_empty ( ) {
111127 // contains([], x) is always false.
112128 return Some ( lit ( true ) ) ;
113129 }
114- let value_max = expr . needle ( ) . stat_max ( catalog) ?;
115- let value_min = expr . needle ( ) . stat_min ( catalog) ?;
130+ let value_max = needle. stat_max ( catalog) ?;
131+ let value_min = needle. stat_min ( catalog) ?;
116132
117133 return list_
118134 . iter ( )
@@ -143,17 +159,7 @@ impl VTable for ListContains {
143159/// let expr = list_contains(root(), lit(42));
144160/// ```
145161pub fn list_contains ( list : Expression , value : Expression ) -> Expression {
146- ListContains . new_expr ( ( ) , [ list, value] )
147- }
148-
149- impl ExpressionView < ' _ , ListContains > {
150- pub fn list ( & self ) -> & Expression {
151- & self . children ( ) [ 0 ]
152- }
153-
154- pub fn needle ( & self ) -> & Expression {
155- & self . children ( ) [ 1 ]
156- }
162+ ListContains . new_expr ( EmptyOptions , [ list, value] )
157163}
158164
159165#[ cfg( test) ]
0 commit comments