Skip to content

Commit

Permalink
Fix incorrect parsing of JsonAccess bracket notation after cast in Sn…
Browse files Browse the repository at this point in the history
…owflake (#1708)
  • Loading branch information
yoavcloud authored Feb 6, 2025
1 parent 0b8ba91 commit 86abbd6
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 10 deletions.
5 changes: 5 additions & 0 deletions src/dialect/duckdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,9 @@ impl Dialect for DuckDbDialect {
fn supports_load_extension(&self) -> bool {
true
}

// See DuckDB <https://duckdb.org/docs/sql/data_types/array.html#defining-an-array-field>
fn supports_array_typedef_size(&self) -> bool {
true
}
}
4 changes: 4 additions & 0 deletions src/dialect/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,8 @@ impl Dialect for GenericDialect {
fn supports_string_escape_constant(&self) -> bool {
true
}

fn supports_array_typedef_size(&self) -> bool {
true
}
}
6 changes: 6 additions & 0 deletions src/dialect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,12 @@ pub trait Dialect: Debug + Any {
fn requires_single_line_comment_whitespace(&self) -> bool {
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
Expand Down
5 changes: 5 additions & 0 deletions src/dialect/postgresql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ impl Dialect for PostgreSqlDialect {
fn supports_numeric_literal_underscores(&self) -> bool {
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>> {
Expand Down
17 changes: 7 additions & 10 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8943,16 +8943,13 @@ impl<'a> Parser<'a> {
_ => self.expected_at("a data type name", next_token_index),
}?;

// Parse array data types. Note: this is postgresql-specific and different from
// Keyword::ARRAY syntax from above
while self.consume_token(&Token::LBracket) {
let size = if dialect_of!(self is GenericDialect | DuckDbDialect | PostgreSqlDialect) {
self.maybe_parse(|p| p.parse_literal_uint())?
} else {
None
};
self.expect_token(&Token::RBracket)?;
data = DataType::Array(ArrayElemTypeDef::SquareBracket(Box::new(data), size))
if self.dialect.supports_array_typedef_size() {
// Parse array data type size
while self.consume_token(&Token::LBracket) {
let size = self.maybe_parse(|p| p.parse_literal_uint())?;
self.expect_token(&Token::RBracket)?;
data = DataType::Array(ArrayElemTypeDef::SquareBracket(Box::new(data), size))
}
}
Ok((data, trailing_bracket))
}
Expand Down
26 changes: 26 additions & 0 deletions tests/sqlparser_snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,32 @@ fn parse_semi_structured_data_traversal() {
.to_string(),
"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]
Expand Down

0 comments on commit 86abbd6

Please sign in to comment.