@@ -3237,6 +3237,121 @@ fn parse_interval() {
3237
3237
) ;
3238
3238
}
3239
3239
3240
+ #[ test]
3241
+ fn parse_interval_and_or_xor ( ) {
3242
+ let sql = "SELECT col FROM test \
3243
+ WHERE d3_date > d1_date + INTERVAL '5 days' \
3244
+ AND d2_date > d1_date + INTERVAL '3 days'";
3245
+
3246
+ let actual_ast = Parser :: parse_sql ( & GenericDialect { } , sql) . unwrap ( ) ;
3247
+
3248
+ let expected_ast = vec ! [ Statement :: Query ( Box :: new( Query {
3249
+ with: None ,
3250
+ body: Box :: new( SetExpr :: Select ( Box :: new( Select {
3251
+ distinct: false ,
3252
+ top: None ,
3253
+ projection: vec![ UnnamedExpr ( Expr :: Identifier ( Ident {
3254
+ value: "col" . to_string( ) ,
3255
+ quote_style: None ,
3256
+ } ) ) ] ,
3257
+ into: None ,
3258
+ from: vec![ TableWithJoins {
3259
+ relation: TableFactor :: Table {
3260
+ name: ObjectName ( vec![ Ident {
3261
+ value: "test" . to_string( ) ,
3262
+ quote_style: None ,
3263
+ } ] ) ,
3264
+ alias: None ,
3265
+ args: None ,
3266
+ with_hints: vec![ ] ,
3267
+ } ,
3268
+ joins: vec![ ] ,
3269
+ } ] ,
3270
+ lateral_views: vec![ ] ,
3271
+ selection: Some ( Expr :: BinaryOp {
3272
+ left: Box :: new( Expr :: BinaryOp {
3273
+ left: Box :: new( Expr :: Identifier ( Ident {
3274
+ value: "d3_date" . to_string( ) ,
3275
+ quote_style: None ,
3276
+ } ) ) ,
3277
+ op: BinaryOperator :: Gt ,
3278
+ right: Box :: new( Expr :: BinaryOp {
3279
+ left: Box :: new( Expr :: Identifier ( Ident {
3280
+ value: "d1_date" . to_string( ) ,
3281
+ quote_style: None ,
3282
+ } ) ) ,
3283
+ op: BinaryOperator :: Plus ,
3284
+ right: Box :: new( Expr :: Interval {
3285
+ value: Box :: new( Expr :: Value ( Value :: SingleQuotedString (
3286
+ "5 days" . to_string( ) ,
3287
+ ) ) ) ,
3288
+ leading_field: None ,
3289
+ leading_precision: None ,
3290
+ last_field: None ,
3291
+ fractional_seconds_precision: None ,
3292
+ } ) ,
3293
+ } ) ,
3294
+ } ) ,
3295
+ op: BinaryOperator :: And ,
3296
+ right: Box :: new( Expr :: BinaryOp {
3297
+ left: Box :: new( Expr :: Identifier ( Ident {
3298
+ value: "d2_date" . to_string( ) ,
3299
+ quote_style: None ,
3300
+ } ) ) ,
3301
+ op: BinaryOperator :: Gt ,
3302
+ right: Box :: new( Expr :: BinaryOp {
3303
+ left: Box :: new( Expr :: Identifier ( Ident {
3304
+ value: "d1_date" . to_string( ) ,
3305
+ quote_style: None ,
3306
+ } ) ) ,
3307
+ op: BinaryOperator :: Plus ,
3308
+ right: Box :: new( Expr :: Interval {
3309
+ value: Box :: new( Expr :: Value ( Value :: SingleQuotedString (
3310
+ "3 days" . to_string( ) ,
3311
+ ) ) ) ,
3312
+ leading_field: None ,
3313
+ leading_precision: None ,
3314
+ last_field: None ,
3315
+ fractional_seconds_precision: None ,
3316
+ } ) ,
3317
+ } ) ,
3318
+ } ) ,
3319
+ } ) ,
3320
+ group_by: vec![ ] ,
3321
+ cluster_by: vec![ ] ,
3322
+ distribute_by: vec![ ] ,
3323
+ sort_by: vec![ ] ,
3324
+ having: None ,
3325
+ qualify: None ,
3326
+ } ) ) ) ,
3327
+ order_by: vec![ ] ,
3328
+ limit: None ,
3329
+ offset: None ,
3330
+ fetch: None ,
3331
+ lock: None ,
3332
+ } ) ) ] ;
3333
+
3334
+ assert_eq ! ( actual_ast, expected_ast) ;
3335
+
3336
+ verified_stmt (
3337
+ "SELECT col FROM test \
3338
+ WHERE d3_date > d1_date + INTERVAL '5 days' \
3339
+ AND d2_date > d1_date + INTERVAL '3 days'",
3340
+ ) ;
3341
+
3342
+ verified_stmt (
3343
+ "SELECT col FROM test \
3344
+ WHERE d3_date > d1_date + INTERVAL '5 days' \
3345
+ OR d2_date > d1_date + INTERVAL '3 days'",
3346
+ ) ;
3347
+
3348
+ verified_stmt (
3349
+ "SELECT col FROM test \
3350
+ WHERE d3_date > d1_date + INTERVAL '5 days' \
3351
+ XOR d2_date > d1_date + INTERVAL '3 days'",
3352
+ ) ;
3353
+ }
3354
+
3240
3355
#[ test]
3241
3356
fn parse_at_timezone ( ) {
3242
3357
let zero = Expr :: Value ( number ( "0" ) ) ;
0 commit comments