@@ -61,62 +61,90 @@ fn like_pattern_str(value: &Expression) -> VortexResult<Option<String>> {
6161 }
6262}
6363
64- pub fn try_from_bound_expression ( value : & Expression ) -> VortexResult < ExprRef > {
64+ pub fn try_from_bound_expression ( value : & Expression ) -> VortexResult < Option < ExprRef > > {
6565 let Some ( value) = value. as_class ( ) else {
66- vortex_bail ! ( "no expression class" )
66+ vortex_bail ! ( "no expression class id {:?}" , value . as_class_id ( ) )
6767 } ;
68- Ok ( match value {
68+ Ok ( Some ( match value {
6969 ExpressionClass :: BoundColumnRef ( col) => get_item_scope ( col. name . to_str ( ) ?) ,
7070 ExpressionClass :: BoundConstant ( const_) => lit ( Scalar :: try_from ( const_. value ) ?) ,
7171 ExpressionClass :: BoundComparison ( compare) => {
7272 let operator: Operator = compare. op . try_into ( ) ?;
7373
74- BinaryExpr :: new_expr (
75- try_from_bound_expression ( & compare. left ) ?,
76- operator,
77- try_from_bound_expression ( & compare. right ) ?,
78- )
74+ let Some ( left) = try_from_bound_expression ( & compare. left ) ? else {
75+ return Ok ( None ) ;
76+ } ;
77+ let Some ( right) = try_from_bound_expression ( & compare. right ) ? else {
78+ return Ok ( None ) ;
79+ } ;
80+
81+ BinaryExpr :: new_expr ( left, operator, right)
7982 }
80- ExpressionClass :: BoundBetween ( between) => Between :: between (
81- try_from_bound_expression ( & between. input ) ?,
82- try_from_bound_expression ( & between. lower ) ?,
83- try_from_bound_expression ( & between. upper ) ?,
84- BetweenOptions {
85- lower_strict : if between. lower_inclusive {
86- StrictComparison :: NonStrict
87- } else {
88- StrictComparison :: Strict
89- } ,
90- upper_strict : if between. upper_inclusive {
91- StrictComparison :: NonStrict
92- } else {
93- StrictComparison :: Strict
83+ ExpressionClass :: BoundBetween ( between) => {
84+ let Some ( array) = try_from_bound_expression ( & between. input ) ? else {
85+ return Ok ( None ) ;
86+ } ;
87+ let Some ( lower) = try_from_bound_expression ( & between. lower ) ? else {
88+ return Ok ( None ) ;
89+ } ;
90+ let Some ( upper) = try_from_bound_expression ( & between. upper ) ? else {
91+ return Ok ( None ) ;
92+ } ;
93+ Between :: between (
94+ array,
95+ lower,
96+ upper,
97+ BetweenOptions {
98+ lower_strict : if between. lower_inclusive {
99+ StrictComparison :: NonStrict
100+ } else {
101+ StrictComparison :: Strict
102+ } ,
103+ upper_strict : if between. upper_inclusive {
104+ StrictComparison :: NonStrict
105+ } else {
106+ StrictComparison :: Strict
107+ } ,
94108 } ,
95- } ,
96- ) ,
109+ )
110+ }
97111 ExpressionClass :: BoundOperator ( operator) => match operator. op {
98112 DUCKDB_VX_EXPR_TYPE :: DUCKDB_VX_EXPR_TYPE_OPERATOR_NOT => {
99113 let children = operator. children ( ) . collect_vec ( ) ;
100114 assert_eq ! ( children. len( ) , 1 ) ;
101- let child = try_from_bound_expression ( & children[ 0 ] ) ?;
115+ let Some ( child) = try_from_bound_expression ( & children[ 0 ] ) ? else {
116+ return Ok ( None ) ;
117+ } ;
102118 Not :: new_expr ( child)
103119 }
104120 DUCKDB_VX_EXPR_TYPE :: DUCKDB_VX_EXPR_TYPE_COMPARE_IN => {
105121 // First child is element, rest form the list.
106122 let children = operator. children ( ) . collect_vec ( ) ;
107123 assert ! ( children. len( ) >= 2 ) ;
108- let element = try_from_bound_expression ( & children[ 0 ] ) ?;
124+ let Some ( element) = try_from_bound_expression ( & children[ 0 ] ) ? else {
125+ return Ok ( None ) ;
126+ } ;
109127
110- let list_elements = children
128+ let Some ( list_elements) = children
111129 . iter ( )
112130 . skip ( 1 )
113131 . map ( |c| {
114- Ok ( Literal :: maybe_from ( & try_from_bound_expression ( c) ?)
115- . ok_or_else ( || vortex_err ! ( "cannot have a non literal in a in_list" ) ) ?
116- . value ( )
117- . clone ( ) )
132+ let Some ( value) = try_from_bound_expression ( c) ? else {
133+ return Ok ( None ) ;
134+ } ;
135+ Ok ( Some (
136+ Literal :: maybe_from ( & value)
137+ . ok_or_else ( || {
138+ vortex_err ! ( "cannot have a non literal in a in_list" )
139+ } ) ?
140+ . value ( )
141+ . clone ( ) ,
142+ ) )
118143 } )
119- . collect :: < VortexResult < Vec < _ > > > ( ) ?;
144+ . collect :: < VortexResult < Option < Vec < _ > > > > ( ) ?
145+ else {
146+ return Ok ( None ) ;
147+ } ;
120148 let list = Scalar :: list (
121149 Arc :: new ( list_elements[ 0 ] . dtype ( ) . clone ( ) ) ,
122150 list_elements,
@@ -130,16 +158,39 @@ pub fn try_from_bound_expression(value: &Expression) -> VortexResult<ExprRef> {
130158 DUCKDB_FUNCTION_NAME_CONTAINS => {
131159 let children = func. children ( ) . collect_vec ( ) ;
132160 assert_eq ! ( children. len( ) , 2 ) ;
133- let value = try_from_bound_expression ( & children[ 0 ] ) ?;
161+ let Some ( value) = try_from_bound_expression ( & children[ 0 ] ) ? else {
162+ return Ok ( None ) ;
163+ } ;
134164 let Some ( pattern_lit) = like_pattern_str ( & children[ 1 ] ) ? else {
135165 vortex_bail ! ( "expected pattern to be bound string" )
136166 } ;
137167 let pattern = Literal :: new_expr ( pattern_lit) ;
138168 Like :: new_expr ( value, pattern, false , false )
139169 }
140- _ => todo ! ( ) ,
170+ _ => {
171+ log:: warn!( "bound function {}" , func. scalar_function. name( ) ) ;
172+ return Ok ( None ) ;
173+ }
141174 } ,
142- } )
175+ ExpressionClass :: BoundConjunction ( conj) => {
176+ let Some ( children) = conj
177+ . children ( )
178+ . map ( |c| try_from_bound_expression ( & c) )
179+ . collect :: < VortexResult < Option < Vec < _ > > > > ( ) ?
180+ else {
181+ return Ok ( None ) ;
182+ } ;
183+ match conj. op {
184+ DUCKDB_VX_EXPR_TYPE :: DUCKDB_VX_EXPR_TYPE_CONJUNCTION_AND => {
185+ and_collect ( children) . vortex_expect ( "cannot be empty" )
186+ }
187+ DUCKDB_VX_EXPR_TYPE :: DUCKDB_VX_EXPR_TYPE_CONJUNCTION_OR => {
188+ or_collect ( children) . vortex_expect ( "cannot be empty" )
189+ }
190+ _ => vortex_bail ! ( "unexpected operator {:?} in bound conjunction" , conj. op) ,
191+ }
192+ }
193+ } ) )
143194}
144195
145196impl TryFrom < DUCKDB_VX_EXPR_TYPE > for Operator {
0 commit comments