feat: support BIGNUMERIC of bigquery (#811)

* add tests

* bignumeric data type

* bignumeric keyword

* fix doc

* add exact_number_info

* fix doc

* check result string
This commit is contained in:
Y Togami 2023-03-03 00:38:00 +09:00 committed by GitHub
parent b45306819c
commit fbbf1a4e84
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 0 deletions

View file

@ -79,6 +79,14 @@ pub enum DataType {
///
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type
Decimal(ExactNumberInfo),
/// [BigNumeric] type used in BigQuery
///
/// [BigNumeric]: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#bignumeric_literals
BigNumeric(ExactNumberInfo),
/// This is alias for `BigNumeric` type used in BigQuery
///
/// [BigDecimal]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#decimal_types
BigDecimal(ExactNumberInfo),
/// Dec type with optional precision and scale e.g. DEC(10,2), [standard][1]
///
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type
@ -196,6 +204,8 @@ impl fmt::Display for DataType {
DataType::Dec(info) => {
write!(f, "DEC{info}")
}
DataType::BigNumeric(info) => write!(f, "BIGNUMERIC{info}"),
DataType::BigDecimal(info) => write!(f, "BIGDECIMAL{info}"),
DataType::Float(size) => format_type_with_optional_length(f, "FLOAT", size, false),
DataType::TinyInt(zerofill) => {
format_type_with_optional_length(f, "TINYINT", zerofill, false)

View file

@ -104,7 +104,9 @@ define_keywords!(
BEGIN_FRAME,
BEGIN_PARTITION,
BETWEEN,
BIGDECIMAL,
BIGINT,
BIGNUMERIC,
BINARY,
BLOB,
BOOLEAN,

View file

@ -4432,6 +4432,12 @@ impl<'a> Parser<'a> {
Keyword::DEC => Ok(DataType::Dec(
self.parse_exact_number_optional_precision_scale()?,
)),
Keyword::BIGNUMERIC => Ok(DataType::BigNumeric(
self.parse_exact_number_optional_precision_scale()?,
)),
Keyword::BIGDECIMAL => Ok(DataType::BigDecimal(
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 => {

View file

@ -3658,6 +3658,75 @@ fn parse_json_keyword() {
);
}
#[test]
fn parse_bignumeric_keyword() {
let sql = r#"SELECT BIGNUMERIC '0'"#;
let select = verified_only_select(sql);
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
value: r#"0"#.into()
},
expr_from_projection(only(&select.projection)),
);
verified_stmt("SELECT BIGNUMERIC '0'");
let sql = r#"SELECT BIGNUMERIC '123456'"#;
let select = verified_only_select(sql);
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
value: r#"123456"#.into()
},
expr_from_projection(only(&select.projection)),
);
verified_stmt("SELECT BIGNUMERIC '123456'");
let sql = r#"SELECT BIGNUMERIC '-3.14'"#;
let select = verified_only_select(sql);
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
value: r#"-3.14"#.into()
},
expr_from_projection(only(&select.projection)),
);
verified_stmt("SELECT BIGNUMERIC '-3.14'");
let sql = r#"SELECT BIGNUMERIC '-0.54321'"#;
let select = verified_only_select(sql);
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
value: r#"-0.54321"#.into()
},
expr_from_projection(only(&select.projection)),
);
verified_stmt("SELECT BIGNUMERIC '-0.54321'");
let sql = r#"SELECT BIGNUMERIC '1.23456e05'"#;
let select = verified_only_select(sql);
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
value: r#"1.23456e05"#.into()
},
expr_from_projection(only(&select.projection)),
);
verified_stmt("SELECT BIGNUMERIC '1.23456e05'");
let sql = r#"SELECT BIGNUMERIC '-9.876e-3'"#;
let select = verified_only_select(sql);
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
value: r#"-9.876e-3"#.into()
},
expr_from_projection(only(&select.projection)),
);
verified_stmt("SELECT BIGNUMERIC '-9.876e-3'");
}
#[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";