Ensure numbers are parsed properly

This change fixes a bug where `100test` would be parsed as a number, and the parser would subsequently fail. Now the value is only parsed as a number if it is immediately followed by an allowed character - otherwise it will fail, and the value `100test` will be parsed as an ident instead.
This commit is contained in:
Tobie Morgan Hitchcock 2022-03-16 15:50:08 +00:00
parent f855e721e8
commit 1b0477ae29

View file

@ -1,8 +1,16 @@
use crate::sql::comment::comment;
use crate::sql::error::IResult; use crate::sql::error::IResult;
use crate::sql::operator::{assigner, operator};
use dec::prelude::FromPrimitive; use dec::prelude::FromPrimitive;
use dec::prelude::ToPrimitive; use dec::prelude::ToPrimitive;
use dec::Decimal; use dec::Decimal;
use dec::MathematicalOps; use dec::MathematicalOps;
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete::multispace1;
use nom::combinator::eof;
use nom::combinator::map;
use nom::combinator::peek;
use nom::number::complete::recognize_float; use nom::number::complete::recognize_float;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::cmp::Ordering; use std::cmp::Ordering;
@ -504,6 +512,17 @@ impl<'a> Product<&'a Self> for Number {
pub fn number(i: &str) -> IResult<&str, Number> { pub fn number(i: &str) -> IResult<&str, Number> {
let (i, v) = recognize_float(i)?; let (i, v) = recognize_float(i)?;
let (i, _) = peek(alt((
map(multispace1, |_| ()),
map(operator, |_| ()),
map(assigner, |_| ()),
map(comment, |_| ()),
map(tag("]"), |_| ()),
map(tag("}"), |_| ()),
map(tag(";"), |_| ()),
map(tag(","), |_| ()),
map(eof, |_| ()),
)))(i)?;
Ok((i, Number::from(v))) Ok((i, Number::from(v)))
} }