From 491b549f1da1796ca0b9b79770a1adcb603fda98 Mon Sep 17 00:00:00 2001 From: Mees Delzenne Date: Thu, 19 Sep 2024 16:14:32 +0200 Subject: [PATCH] Fix decimal parsing (#4838) --- core/src/syn/lexer/compound/number.rs | 9 ++++++++- core/src/syn/parser/test/mod.rs | 5 +++++ core/src/syn/parser/test/value.rs | 7 +++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/core/src/syn/lexer/compound/number.rs b/core/src/syn/lexer/compound/number.rs index 54ca7e98..501ab57a 100644 --- a/core/src/syn/lexer/compound/number.rs +++ b/core/src/syn/lexer/compound/number.rs @@ -82,9 +82,16 @@ pub fn numeric(lexer: &mut Lexer, start: Token) -> Result match start.kind { t!("-") | t!("+") => number(lexer, start).map(Numeric::Number), TokenKind::Digits => match lexer.reader.peek() { - Some(b'n' | b'm' | b's' | b'h' | b'y' | b'd' | b'w') => { + Some(b'n' | b'm' | b's' | b'h' | b'y' | b'w') => { duration(lexer, start).map(Numeric::Duration) } + Some(b'd') => { + if lexer.reader.peek1() == Some(b'e') { + number(lexer, start).map(Numeric::Number) + } else { + duration(lexer, start).map(Numeric::Duration) + } + } Some(x) if !x.is_ascii() => duration(lexer, start).map(Numeric::Duration), _ => number(lexer, start).map(Numeric::Number), }, diff --git a/core/src/syn/parser/test/mod.rs b/core/src/syn/parser/test/mod.rs index 8cbc32a3..73f73735 100644 --- a/core/src/syn/parser/test/mod.rs +++ b/core/src/syn/parser/test/mod.rs @@ -9,6 +9,11 @@ mod stmt; mod streaming; mod value; +#[test] +fn parse_large_test_file() { + test_parse!(parse_query, include_str!("../../../../test.surql")).unwrap(); +} + #[test] fn multiple_semicolons() { let res = test_parse!(parse_query, r#";;"#).unwrap(); diff --git a/core/src/syn/parser/test/value.rs b/core/src/syn/parser/test/value.rs index 976052ca..16693923 100644 --- a/core/src/syn/parser/test/value.rs +++ b/core/src/syn/parser/test/value.rs @@ -1,6 +1,7 @@ use std::collections::BTreeMap; use reblessive::Stack; +use rust_decimal::Decimal; use crate::{ sql::{ @@ -156,6 +157,12 @@ fn parse_i64() { assert_eq!(res, Value::Number(Number::Int(i64::MAX))); } +#[test] +fn parse_decimal() { + let res = test_parse!(parse_value_field, r#" 0dec "#).unwrap(); + assert_eq!(res, Value::Number(Number::Decimal(Decimal::ZERO))); +} + #[test] fn constant_lowercase() { let out = test_parse!(parse_value_field, r#" math::pi "#).unwrap();