@@ -3237,6 +3237,121 @@ fn parse_interval() {
32373237 ) ;
32383238}
32393239
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+
32403355#[ test]
32413356fn parse_at_timezone ( ) {
32423357 let zero = Expr :: Value ( number ( "0" ) ) ;
0 commit comments