mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-04 06:18:17 +00:00
Fix incorrect parsing of JsonAccess bracket notation after cast in Snowflake (#1708)
This commit is contained in:
parent
0b8ba91156
commit
86abbd6028
6 changed files with 53 additions and 10 deletions
|
@ -80,4 +80,9 @@ impl Dialect for DuckDbDialect {
|
||||||
fn supports_load_extension(&self) -> bool {
|
fn supports_load_extension(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See DuckDB <https://duckdb.org/docs/sql/data_types/array.html#defining-an-array-field>
|
||||||
|
fn supports_array_typedef_size(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,4 +143,8 @@ impl Dialect for GenericDialect {
|
||||||
fn supports_string_escape_constant(&self) -> bool {
|
fn supports_string_escape_constant(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn supports_array_typedef_size(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -890,6 +890,12 @@ pub trait Dialect: Debug + Any {
|
||||||
fn requires_single_line_comment_whitespace(&self) -> bool {
|
fn requires_single_line_comment_whitespace(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the dialect supports size definition for array types.
|
||||||
|
/// For example: ```CREATE TABLE my_table (my_array INT[3])```.
|
||||||
|
fn supports_array_typedef_size(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This represents the operators for which precedence must be defined
|
/// This represents the operators for which precedence must be defined
|
||||||
|
|
|
@ -253,6 +253,11 @@ impl Dialect for PostgreSqlDialect {
|
||||||
fn supports_numeric_literal_underscores(&self) -> bool {
|
fn supports_numeric_literal_underscores(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// See: <https://www.postgresql.org/docs/current/arrays.html#ARRAYS-DECLARATION>
|
||||||
|
fn supports_array_typedef_size(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_create(parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
|
pub fn parse_create(parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
|
||||||
|
|
|
@ -8943,17 +8943,14 @@ impl<'a> Parser<'a> {
|
||||||
_ => self.expected_at("a data type name", next_token_index),
|
_ => self.expected_at("a data type name", next_token_index),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
// Parse array data types. Note: this is postgresql-specific and different from
|
if self.dialect.supports_array_typedef_size() {
|
||||||
// Keyword::ARRAY syntax from above
|
// Parse array data type size
|
||||||
while self.consume_token(&Token::LBracket) {
|
while self.consume_token(&Token::LBracket) {
|
||||||
let size = if dialect_of!(self is GenericDialect | DuckDbDialect | PostgreSqlDialect) {
|
let size = self.maybe_parse(|p| p.parse_literal_uint())?;
|
||||||
self.maybe_parse(|p| p.parse_literal_uint())?
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
self.expect_token(&Token::RBracket)?;
|
self.expect_token(&Token::RBracket)?;
|
||||||
data = DataType::Array(ArrayElemTypeDef::SquareBracket(Box::new(data), size))
|
data = DataType::Array(ArrayElemTypeDef::SquareBracket(Box::new(data), size))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok((data, trailing_bracket))
|
Ok((data, trailing_bracket))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1256,6 +1256,32 @@ fn parse_semi_structured_data_traversal() {
|
||||||
.to_string(),
|
.to_string(),
|
||||||
"sql parser error: Expected: variant object key name, found: 42"
|
"sql parser error: Expected: variant object key name, found: 42"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// casting a json access and accessing an array element
|
||||||
|
assert_eq!(
|
||||||
|
snowflake().verified_expr("a:b::ARRAY[1]"),
|
||||||
|
Expr::JsonAccess {
|
||||||
|
value: Box::new(Expr::Cast {
|
||||||
|
kind: CastKind::DoubleColon,
|
||||||
|
data_type: DataType::Array(ArrayElemTypeDef::None),
|
||||||
|
format: None,
|
||||||
|
expr: Box::new(Expr::JsonAccess {
|
||||||
|
value: Box::new(Expr::Identifier(Ident::new("a"))),
|
||||||
|
path: JsonPath {
|
||||||
|
path: vec![JsonPathElem::Dot {
|
||||||
|
key: "b".to_string(),
|
||||||
|
quoted: false
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
path: JsonPath {
|
||||||
|
path: vec![JsonPathElem::Bracket {
|
||||||
|
key: Expr::Value(number("1"))
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue