Skip to content

Commit c3cc70c

Browse files
yoavcloudayman-sigma
authored andcommitted
Fix incorrect parsing of JsonAccess bracket notation after cast in Snowflake (apache#1708)
1 parent 0ab3de6 commit c3cc70c

File tree

6 files changed

+53
-10
lines changed

6 files changed

+53
-10
lines changed

src/dialect/duckdb.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,9 @@ impl Dialect for DuckDbDialect {
8080
fn supports_load_extension(&self) -> bool {
8181
true
8282
}
83+
84+
// See DuckDB <https://duckdb.org/docs/sql/data_types/array.html#defining-an-array-field>
85+
fn supports_array_typedef_size(&self) -> bool {
86+
true
87+
}
8388
}

src/dialect/generic.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,8 @@ impl Dialect for GenericDialect {
143143
fn supports_string_escape_constant(&self) -> bool {
144144
true
145145
}
146+
147+
fn supports_array_typedef_size(&self) -> bool {
148+
true
149+
}
146150
}

src/dialect/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,12 @@ pub trait Dialect: Debug + Any {
890890
fn requires_single_line_comment_whitespace(&self) -> bool {
891891
false
892892
}
893+
894+
/// Returns true if the dialect supports size definition for array types.
895+
/// For example: ```CREATE TABLE my_table (my_array INT[3])```.
896+
fn supports_array_typedef_size(&self) -> bool {
897+
false
898+
}
893899
}
894900

895901
/// This represents the operators for which precedence must be defined

src/dialect/postgresql.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ impl Dialect for PostgreSqlDialect {
253253
fn supports_numeric_literal_underscores(&self) -> bool {
254254
true
255255
}
256+
257+
/// See: <https://www.postgresql.org/docs/current/arrays.html#ARRAYS-DECLARATION>
258+
fn supports_array_typedef_size(&self) -> bool {
259+
true
260+
}
256261
}
257262

258263
pub fn parse_create(parser: &mut Parser) -> Option<Result<Statement, ParserError>> {

src/parser/mod.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8953,16 +8953,13 @@ impl<'a> Parser<'a> {
89538953
_ => self.expected_at("a data type name", next_token_index),
89548954
}?;
89558955

8956-
// Parse array data types. Note: this is postgresql-specific and different from
8957-
// Keyword::ARRAY syntax from above
8958-
while self.consume_token(&Token::LBracket) {
8959-
let size = if dialect_of!(self is GenericDialect | DuckDbDialect | PostgreSqlDialect) {
8960-
self.maybe_parse(|p| p.parse_literal_uint())?
8961-
} else {
8962-
None
8963-
};
8964-
self.expect_token(&Token::RBracket)?;
8965-
data = DataType::Array(ArrayElemTypeDef::SquareBracket(Box::new(data), size))
8956+
if self.dialect.supports_array_typedef_size() {
8957+
// Parse array data type size
8958+
while self.consume_token(&Token::LBracket) {
8959+
let size = self.maybe_parse(|p| p.parse_literal_uint())?;
8960+
self.expect_token(&Token::RBracket)?;
8961+
data = DataType::Array(ArrayElemTypeDef::SquareBracket(Box::new(data), size))
8962+
}
89668963
}
89678964
Ok((data, trailing_bracket))
89688965
}

tests/sqlparser_snowflake.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,32 @@ fn parse_semi_structured_data_traversal() {
12561256
.to_string(),
12571257
"sql parser error: Expected: variant object key name, found: 42"
12581258
);
1259+
1260+
// casting a json access and accessing an array element
1261+
assert_eq!(
1262+
snowflake().verified_expr("a:b::ARRAY[1]"),
1263+
Expr::JsonAccess {
1264+
value: Box::new(Expr::Cast {
1265+
kind: CastKind::DoubleColon,
1266+
data_type: DataType::Array(ArrayElemTypeDef::None),
1267+
format: None,
1268+
expr: Box::new(Expr::JsonAccess {
1269+
value: Box::new(Expr::Identifier(Ident::new("a"))),
1270+
path: JsonPath {
1271+
path: vec![JsonPathElem::Dot {
1272+
key: "b".to_string(),
1273+
quoted: false
1274+
}]
1275+
}
1276+
})
1277+
}),
1278+
path: JsonPath {
1279+
path: vec![JsonPathElem::Bracket {
1280+
key: Expr::Value(number("1"))
1281+
}]
1282+
}
1283+
}
1284+
);
12591285
}
12601286

12611287
#[test]

0 commit comments

Comments
 (0)