@@ -221,9 +221,35 @@ fn is_null(i: &[u8]) -> IResult<&[u8], (Operator, ConditionExpression)> {
221
221
) )
222
222
}
223
223
224
+ fn in_operation ( i : & [ u8 ] ) -> IResult < & [ u8 ] , ( Operator , ConditionExpression ) > {
225
+ map (
226
+ separated_pair (
227
+ opt ( terminated ( tag_no_case ( "not" ) , multispace1) ) ,
228
+ terminated ( tag_no_case ( "in" ) , multispace0) ,
229
+ alt ( (
230
+ map ( delimited ( tag ( "(" ) , nested_selection, tag ( ")" ) ) , |s| {
231
+ ConditionBase :: NestedSelect ( Box :: new ( s) )
232
+ } ) ,
233
+ map ( delimited ( tag ( "(" ) , value_list, tag ( ")" ) ) , |vs| {
234
+ ConditionBase :: LiteralList ( vs)
235
+ } ) ,
236
+ ) ) ,
237
+ ) ,
238
+ |p| {
239
+ let nested = ConditionExpression :: Base ( p. 1 ) ;
240
+ if ( p. 0 ) . is_some ( ) {
241
+ ( Operator :: NotIn , nested)
242
+ } else {
243
+ ( Operator :: In , nested)
244
+ }
245
+ } ,
246
+ ) ( i)
247
+ }
248
+
224
249
fn boolean_primary_rest ( i : & [ u8 ] ) -> IResult < & [ u8 ] , ( Operator , ConditionExpression ) > {
225
250
alt ( (
226
251
is_null,
252
+ in_operation,
227
253
separated_pair ( binary_comparison_operator, multispace0, predicate) ,
228
254
) ) ( i)
229
255
}
@@ -245,36 +271,6 @@ fn boolean_primary(i: &[u8]) -> IResult<&[u8], ConditionExpression> {
245
271
}
246
272
247
273
fn predicate ( i : & [ u8 ] ) -> IResult < & [ u8 ] , ConditionExpression > {
248
- let nested_sel_pred = map (
249
- separated_pair (
250
- opt ( preceded ( multispace0, tag_no_case ( "not" ) ) ) ,
251
- delimited ( multispace1, tag_no_case ( "in" ) , multispace1) ,
252
- nested_selection,
253
- ) ,
254
- |p| {
255
- let nested = ConditionExpression :: Base ( ConditionBase :: NestedSelect ( Box :: new ( p. 1 ) ) ) ;
256
- if ( p. 0 ) . is_some ( ) {
257
- ConditionExpression :: NegationOp ( Box :: new ( nested) )
258
- } else {
259
- nested
260
- }
261
- } ,
262
- ) ;
263
- let in_list_pred = map (
264
- separated_pair (
265
- opt ( preceded ( multispace0, tag_no_case ( "not" ) ) ) ,
266
- delimited ( multispace1, tag_no_case ( "in" ) , multispace1) ,
267
- delimited ( tag ( "(" ) , value_list, tag ( ")" ) ) ,
268
- ) ,
269
- |p| {
270
- let list = ConditionExpression :: Base ( ConditionBase :: LiteralList ( p. 1 ) ) ;
271
- if ( p. 0 ) . is_some ( ) {
272
- ConditionExpression :: NegationOp ( Box :: new ( list) )
273
- } else {
274
- list
275
- }
276
- } ,
277
- ) ;
278
274
let nested_exists = map (
279
275
tuple ( (
280
276
opt ( delimited ( multispace0, tag_no_case ( "not" ) , multispace1) ) ,
@@ -296,17 +292,7 @@ fn predicate(i: &[u8]) -> IResult<&[u8], ConditionExpression> {
296
292
) ;
297
293
298
294
alt ( (
299
- map (
300
- pair ( simple_expr, opt ( alt ( ( nested_sel_pred, in_list_pred) ) ) ) ,
301
- |p| match p. 1 {
302
- Some ( right) => ConditionExpression :: ComparisonOp ( ConditionTree {
303
- operator : Operator :: In ,
304
- left : Box :: new ( p. 0 ) ,
305
- right : Box :: new ( right) ,
306
- } ) ,
307
- None => p. 0 ,
308
- } ,
309
- ) ,
295
+ simple_expr,
310
296
nested_exists,
311
297
) ) ( i)
312
298
}
@@ -960,4 +946,23 @@ mod tests {
960
946
let res = res. unwrap ( ) . 1 ;
961
947
assert_eq ! ( res, expected) ;
962
948
}
949
+
950
+ #[ test]
951
+ fn not_in_comparison ( ) {
952
+ use ConditionBase :: * ;
953
+
954
+ let qs1 = b"id not in (1,2)" ;
955
+ let res1 = condition_expr ( qs1) ;
956
+
957
+ let c1 = res1. unwrap ( ) . 1 ;
958
+ let expected1 = flat_condition_tree (
959
+ Operator :: NotIn ,
960
+ Field ( "id" . into ( ) ) ,
961
+ LiteralList ( vec ! [ 1 . into( ) , 2 . into( ) ] ) ,
962
+ ) ;
963
+ assert_eq ! ( c1, expected1) ;
964
+
965
+ let expected1 = "id NOT IN (1, 2)" ;
966
+ assert_eq ! ( format!( "{}" , c1) , expected1) ;
967
+ }
963
968
}
0 commit comments