feat: support JSON keyword (#799)

* feat: support json keyword for bigquery

* chore: fix test

---------

Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
This commit is contained in:
Y Togami 2023-02-18 03:46:30 +09:00 committed by GitHub
parent 488e8a8156
commit 79009f5448
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 0 deletions

View file

@ -140,6 +140,8 @@ pub enum DataType {
Timestamp(Option<u64>, TimezoneInfo),
/// Interval
Interval,
/// JSON type used in BigQuery
JSON,
/// Regclass used in postgresql serial
Regclass,
/// Text
@ -244,6 +246,7 @@ impl fmt::Display for DataType {
format_datetime_precision_and_tz(f, "TIMESTAMP", precision, timezone_info)
}
DataType::Interval => write!(f, "INTERVAL"),
DataType::JSON => write!(f, "JSON"),
DataType::Regclass => write!(f, "REGCLASS"),
DataType::Text => write!(f, "TEXT"),
DataType::String => write!(f, "STRING"),

View file

@ -4365,6 +4365,7 @@ impl<'a> Parser<'a> {
// qualifier that we don't currently support. See
// parse_interval for a taste.
Keyword::INTERVAL => Ok(DataType::Interval),
Keyword::JSON => Ok(DataType::JSON),
Keyword::REGCLASS => Ok(DataType::Regclass),
Keyword::STRING => Ok(DataType::String),
Keyword::TEXT => Ok(DataType::Text),

View file

@ -3598,6 +3598,58 @@ fn parse_at_timezone() {
);
}
#[test]
fn parse_json_keyword() {
let sql = r#"SELECT JSON '{
"id": 10,
"type": "fruit",
"name": "apple",
"on_menu": true,
"recipes":
{
"salads":
[
{ "id": 2001, "type": "Walnut Apple Salad" },
{ "id": 2002, "type": "Apple Spinach Salad" }
],
"desserts":
[
{ "id": 3001, "type": "Apple Pie" },
{ "id": 3002, "type": "Apple Scones" },
{ "id": 3003, "type": "Apple Crumble" }
]
}
}'"#;
let select = verified_only_select(sql);
assert_eq!(
&Expr::TypedString {
data_type: DataType::JSON,
value: r#"{
"id": 10,
"type": "fruit",
"name": "apple",
"on_menu": true,
"recipes":
{
"salads":
[
{ "id": 2001, "type": "Walnut Apple Salad" },
{ "id": 2002, "type": "Apple Spinach Salad" }
],
"desserts":
[
{ "id": 3001, "type": "Apple Pie" },
{ "id": 3002, "type": "Apple Scones" },
{ "id": 3003, "type": "Apple Crumble" }
]
}
}"#
.into()
},
expr_from_projection(only(&select.projection)),
);
}
#[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";