Enum to handle exact number precisios (#654)

This commit is contained in:
AugustoFKL 2022-10-08 06:59:11 -03:00 committed by GitHub
parent a3194ddd52
commit a9939b0a4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 12 deletions

View file

@ -3481,10 +3481,9 @@ impl<'a> Parser<'a> {
Keyword::STRING => Ok(DataType::String),
Keyword::TEXT => Ok(DataType::Text),
Keyword::BYTEA => Ok(DataType::Bytea),
Keyword::NUMERIC | Keyword::DECIMAL | Keyword::DEC => {
let (precision, scale) = self.parse_optional_precision_scale()?;
Ok(DataType::Decimal(precision, scale))
}
Keyword::NUMERIC | Keyword::DECIMAL | Keyword::DEC => Ok(DataType::Decimal(
self.parse_exact_number_optional_precision_scale()?,
)),
Keyword::ENUM => Ok(DataType::Enum(self.parse_string_values()?)),
Keyword::SET => Ok(DataType::Set(self.parse_string_values()?)),
Keyword::ARRAY => {
@ -3698,6 +3697,28 @@ impl<'a> Parser<'a> {
}
}
pub fn parse_exact_number_optional_precision_scale(
&mut self,
) -> Result<ExactNumberInfo, ParserError> {
if self.consume_token(&Token::LParen) {
let precision = self.parse_literal_uint()?;
let scale = if self.consume_token(&Token::Comma) {
Some(self.parse_literal_uint()?)
} else {
None
};
self.expect_token(&Token::RParen)?;
match scale {
None => Ok(ExactNumberInfo::Precision(precision)),
Some(scale) => Ok(ExactNumberInfo::PrecisionAndScale(precision, scale)),
}
} else {
Ok(ExactNumberInfo::None)
}
}
pub fn parse_delete(&mut self) -> Result<Statement, ParserError> {
self.expect_keyword(Keyword::FROM)?;
let table_name = self.parse_table_factor()?;
@ -5311,7 +5332,7 @@ mod tests {
#[cfg(test)]
mod test_parse_data_type {
use crate::ast::{DataType, TimezoneInfo};
use crate::ast::{DataType, ExactNumberInfo, TimezoneInfo};
use crate::dialect::{AnsiDialect, GenericDialect};
use crate::test_utils::TestedDialects;
@ -5351,6 +5372,28 @@ mod tests {
test_parse_data_type!(dialect, "VARCHAR(20)", DataType::Varchar(Some(20)));
}
#[test]
fn test_ansii_exact_numeric_types() {
// Exact numeric types: <https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type>
let dialect = TestedDialects {
dialects: vec![Box::new(GenericDialect {}), Box::new(AnsiDialect {})],
};
test_parse_data_type!(dialect, "NUMERIC", DataType::Decimal(ExactNumberInfo::None));
test_parse_data_type!(
dialect,
"NUMERIC(2)",
DataType::Decimal(ExactNumberInfo::Precision(2))
);
test_parse_data_type!(
dialect,
"NUMERIC(2,10)",
DataType::Decimal(ExactNumberInfo::PrecisionAndScale(2, 10))
);
}
#[test]
fn test_ansii_datetime_types() {
// Datetime types: <https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type>