Merge pull request #103 from benesch/intervals

Support interval literals
This commit is contained in:
Nikhil Benesch 2019-06-09 12:41:57 -04:00 committed by GitHub
commit 2d1e05e21d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 260 additions and 41 deletions

View file

@ -819,9 +819,7 @@ fn parse_extract() {
let res = parse_sql_statements("SELECT EXTRACT(MILLISECOND FROM d)");
assert_eq!(
ParserError::ParserError(
"Expected Date/time field inside of EXTRACT function, found: MILLISECOND".to_string()
),
ParserError::ParserError("Expected date/time field, found: MILLISECOND".to_string()),
res.unwrap_err()
);
}
@ -1189,6 +1187,100 @@ fn parse_literal_timestamp() {
);
}
#[test]
fn parse_literal_interval() {
let sql = "SELECT INTERVAL '1-1' YEAR TO MONTH";
let select = verified_only_select(sql);
assert_eq!(
&ASTNode::SQLValue(Value::Interval {
value: "1-1".into(),
leading_field: SQLDateTimeField::Year,
leading_precision: None,
last_field: Some(SQLDateTimeField::Month),
fractional_seconds_precision: None,
}),
expr_from_projection(only(&select.projection)),
);
let sql = "SELECT INTERVAL '01:01.01' MINUTE (5) TO SECOND (5)";
let select = verified_only_select(sql);
assert_eq!(
&ASTNode::SQLValue(Value::Interval {
value: "01:01.01".into(),
leading_field: SQLDateTimeField::Minute,
leading_precision: Some(5),
last_field: Some(SQLDateTimeField::Second),
fractional_seconds_precision: Some(5),
}),
expr_from_projection(only(&select.projection)),
);
let sql = "SELECT INTERVAL '1' SECOND (5, 4)";
let select = verified_only_select(sql);
assert_eq!(
&ASTNode::SQLValue(Value::Interval {
value: "1".into(),
leading_field: SQLDateTimeField::Second,
leading_precision: Some(5),
last_field: None,
fractional_seconds_precision: Some(4),
}),
expr_from_projection(only(&select.projection)),
);
let sql = "SELECT INTERVAL '10' HOUR";
let select = verified_only_select(sql);
assert_eq!(
&ASTNode::SQLValue(Value::Interval {
value: "10".into(),
leading_field: SQLDateTimeField::Hour,
leading_precision: None,
last_field: None,
fractional_seconds_precision: None,
}),
expr_from_projection(only(&select.projection)),
);
let sql = "SELECT INTERVAL '10' HOUR (1)";
let select = verified_only_select(sql);
assert_eq!(
&ASTNode::SQLValue(Value::Interval {
value: "10".into(),
leading_field: SQLDateTimeField::Hour,
leading_precision: Some(1),
last_field: None,
fractional_seconds_precision: None,
}),
expr_from_projection(only(&select.projection)),
);
let result = parse_sql_statements("SELECT INTERVAL '1' SECOND TO SECOND");
assert_eq!(
ParserError::ParserError("Expected end of statement, found: SECOND".to_string()),
result.unwrap_err(),
);
let result = parse_sql_statements("SELECT INTERVAL '10' HOUR (1) TO HOUR (2)");
assert_eq!(
ParserError::ParserError("Expected end of statement, found: (".to_string()),
result.unwrap_err(),
);
verified_only_select("SELECT INTERVAL '1' YEAR");
verified_only_select("SELECT INTERVAL '1' MONTH");
verified_only_select("SELECT INTERVAL '1' DAY");
verified_only_select("SELECT INTERVAL '1' HOUR");
verified_only_select("SELECT INTERVAL '1' MINUTE");
verified_only_select("SELECT INTERVAL '1' SECOND");
verified_only_select("SELECT INTERVAL '1' YEAR TO MONTH");
verified_only_select("SELECT INTERVAL '1' DAY TO HOUR");
verified_only_select("SELECT INTERVAL '1' DAY TO MINUTE");
verified_only_select("SELECT INTERVAL '1' DAY TO SECOND");
verified_only_select("SELECT INTERVAL '1' HOUR TO MINUTE");
verified_only_select("SELECT INTERVAL '1' HOUR TO SECOND");
verified_only_select("SELECT INTERVAL '1' MINUTE TO SECOND");
}
#[test]
fn parse_simple_math_expr_plus() {
let sql = "SELECT a + b, 2 + a, 2.5 + a, a_f + b_f, 2 + a_f, 2.5 + a_f FROM c";