add support for JSON_TABLE (#1062)

This commit is contained in:
Ophir LOJKINE 2023-12-19 21:04:09 +01:00 committed by GitHub
parent 1933f194e7
commit f46f147ffa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 238 additions and 5 deletions

View file

@ -6913,6 +6913,7 @@ impl<'a> Parser<'a> {
| TableFactor::Table { alias, .. }
| TableFactor::Function { alias, .. }
| TableFactor::UNNEST { alias, .. }
| TableFactor::JsonTable { alias, .. }
| TableFactor::TableFunction { alias, .. }
| TableFactor::Pivot { alias, .. }
| TableFactor::Unpivot { alias, .. }
@ -6971,6 +6972,23 @@ impl<'a> Parser<'a> {
with_offset,
with_offset_alias,
})
} else if self.parse_keyword(Keyword::JSON_TABLE) {
self.expect_token(&Token::LParen)?;
let json_expr = self.parse_expr()?;
self.expect_token(&Token::Comma)?;
let json_path = self.parse_value()?;
self.expect_keyword(Keyword::COLUMNS)?;
self.expect_token(&Token::LParen)?;
let columns = self.parse_comma_separated(Parser::parse_json_table_column_def)?;
self.expect_token(&Token::RParen)?;
self.expect_token(&Token::RParen)?;
let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
Ok(TableFactor::JsonTable {
json_expr,
json_path,
columns,
alias,
})
} else {
let name = self.parse_object_name()?;
@ -7041,6 +7059,50 @@ impl<'a> Parser<'a> {
}
}
/// Parses MySQL's JSON_TABLE column definition.
/// For example: `id INT EXISTS PATH '$' DEFAULT '0' ON EMPTY ERROR ON ERROR`
pub fn parse_json_table_column_def(&mut self) -> Result<JsonTableColumn, ParserError> {
let name = self.parse_identifier()?;
let r#type = self.parse_data_type()?;
let exists = self.parse_keyword(Keyword::EXISTS);
self.expect_keyword(Keyword::PATH)?;
let path = self.parse_value()?;
let mut on_empty = None;
let mut on_error = None;
while let Some(error_handling) = self.parse_json_table_column_error_handling()? {
if self.parse_keyword(Keyword::EMPTY) {
on_empty = Some(error_handling);
} else {
self.expect_keyword(Keyword::ERROR)?;
on_error = Some(error_handling);
}
}
Ok(JsonTableColumn {
name,
r#type,
path,
exists,
on_empty,
on_error,
})
}
fn parse_json_table_column_error_handling(
&mut self,
) -> Result<Option<JsonTableColumnErrorHandling>, ParserError> {
let res = if self.parse_keyword(Keyword::NULL) {
JsonTableColumnErrorHandling::Null
} else if self.parse_keyword(Keyword::ERROR) {
JsonTableColumnErrorHandling::Error
} else if self.parse_keyword(Keyword::DEFAULT) {
JsonTableColumnErrorHandling::Default(self.parse_value()?)
} else {
return Ok(None);
};
self.expect_keyword(Keyword::ON)?;
Ok(Some(res))
}
pub fn parse_derived_table_factor(
&mut self,
lateral: IsLateral,