mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-22 23:14:07 +00:00
Fix parse_time() handling of fractional seconds
There's no Token::Period in such situation, so fractional part (from sec) was silently truncated.
Can't uncomment the test yet, because parse_timestamp() is effectively
unused: the code added to parse_value() in 5abd9e7dec
was wrong as it attempted to handle unquoted date/time literals. One
part of it was commented out earlier, the other can't work as far as I
can see, as it tries to parse a Number token - `([0-9]|\.)+` - as a
timestamp, so I removed it as well.
This commit is contained in:
parent
52277c3025
commit
3b13e153a8
2 changed files with 18 additions and 35 deletions
|
@ -682,30 +682,13 @@ impl Parser {
|
|||
"NULL" => Ok(Value::Null),
|
||||
_ => return parser_err!(format!("No value parser for keyword {}", k)),
|
||||
},
|
||||
//TODO: parse the timestamp here
|
||||
//TODO: parse the timestamp here (see parse_timestamp_value())
|
||||
Token::Number(ref n) if n.contains(".") => match n.parse::<f64>() {
|
||||
Ok(n) => Ok(Value::Double(n)),
|
||||
Err(e) => {
|
||||
let index = self.index;
|
||||
self.prev_token();
|
||||
if let Ok(timestamp) = self.parse_timestamp_value() {
|
||||
println!("timstamp: {:?}", timestamp);
|
||||
Ok(timestamp)
|
||||
} else {
|
||||
self.index = index;
|
||||
parser_err!(format!("Could not parse '{}' as i64: {}", n, e))
|
||||
}
|
||||
}
|
||||
Err(e) => parser_err!(format!("Could not parse '{}' as i64: {}", n, e)),
|
||||
},
|
||||
Token::Number(ref n) => match n.parse::<i64>() {
|
||||
Ok(n) => {
|
||||
// if let Some(Token::Minus) = self.peek_token() {
|
||||
// self.prev_token();
|
||||
// self.parse_timestamp_value()
|
||||
// } else {
|
||||
Ok(Value::Long(n))
|
||||
// }
|
||||
}
|
||||
Ok(n) => Ok(Value::Long(n)),
|
||||
Err(e) => parser_err!(format!("Could not parse '{}' as i64: {}", n, e)),
|
||||
},
|
||||
Token::Identifier(id) => Ok(Value::String(id.to_string())),
|
||||
|
@ -733,13 +716,13 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parse a literal integer/long
|
||||
/// Parse a literal double
|
||||
pub fn parse_literal_double(&mut self) -> Result<f64, ParserError> {
|
||||
match self.next_token() {
|
||||
Some(Token::Number(s)) => s.parse::<f64>().map_err(|e| {
|
||||
ParserError::ParserError(format!("Could not parse '{}' as i64: {}", s, e))
|
||||
ParserError::ParserError(format!("Could not parse '{}' as f64: {}", s, e))
|
||||
}),
|
||||
other => parser_err!(format!("Expected literal int, found {:?}", other)),
|
||||
other => parser_err!(format!("Expected literal number, found {:?}", other)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -820,19 +803,17 @@ impl Parser {
|
|||
self.consume_token(&Token::Colon)?;
|
||||
let min = self.parse_literal_int()?;
|
||||
self.consume_token(&Token::Colon)?;
|
||||
// On one hand, the SQL specs defines <seconds fraction> ::= <unsigned integer>,
|
||||
// so it would be more correct to parse it as such
|
||||
let sec = self.parse_literal_double()?;
|
||||
let _ = (sec.fract() * 1000.0).round();
|
||||
if let Ok(true) = self.consume_token(&Token::Period) {
|
||||
let ms = self.parse_literal_int()?;
|
||||
Ok(NaiveTime::from_hms_milli(
|
||||
// On the other, chrono only supports nanoseconds, which should(?) fit in seconds-as-f64...
|
||||
let nanos = (sec.fract() * 1_000_000_000.0).round();
|
||||
Ok(NaiveTime::from_hms_nano(
|
||||
hour as u32,
|
||||
min as u32,
|
||||
sec as u32,
|
||||
ms as u32,
|
||||
nanos as u32,
|
||||
))
|
||||
} else {
|
||||
Ok(NaiveTime::from_hms(hour as u32, min as u32, sec as u32))
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a SQL datatype (in the context of a CREATE TABLE statement for example)
|
||||
|
|
|
@ -657,6 +657,7 @@ fn parse_timestamps_example() {
|
|||
let sql = "2016-02-15 09:43:33";
|
||||
let _ = parse_sql(sql);
|
||||
//TODO add assertion
|
||||
//assert_eq!(sql, ast.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -664,6 +665,7 @@ fn parse_timestamps_with_millis_example() {
|
|||
let sql = "2017-11-02 19:15:42.308637";
|
||||
let _ = parse_sql(sql);
|
||||
//TODO add assertion
|
||||
//assert_eq!(sql, ast.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue