This is an automated email from the ASF dual-hosted git repository.
iffyio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 86abbd60 Fix incorrect parsing of JsonAccess bracket notation after
cast in Snowflake (#1708)
86abbd60 is described below
commit 86abbd6028d72cee5fa299bc171f492fb722157c
Author: Yoav Cohen <[email protected]>
AuthorDate: Thu Feb 6 18:14:03 2025 +0100
Fix incorrect parsing of JsonAccess bracket notation after cast in
Snowflake (#1708)
---
src/dialect/duckdb.rs | 5 +++++
src/dialect/generic.rs | 4 ++++
src/dialect/mod.rs | 6 ++++++
src/dialect/postgresql.rs | 5 +++++
src/parser/mod.rs | 17 +++++++----------
tests/sqlparser_snowflake.rs | 26 ++++++++++++++++++++++++++
6 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/src/dialect/duckdb.rs b/src/dialect/duckdb.rs
index c41aec81..e8dcf853 100644
--- a/src/dialect/duckdb.rs
+++ b/src/dialect/duckdb.rs
@@ -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
+ }
}
diff --git a/src/dialect/generic.rs b/src/dialect/generic.rs
index 4021b575..7aaf0074 100644
--- a/src/dialect/generic.rs
+++ b/src/dialect/generic.rs
@@ -143,4 +143,8 @@ impl Dialect for GenericDialect {
fn supports_string_escape_constant(&self) -> bool {
true
}
+
+ fn supports_array_typedef_size(&self) -> bool {
+ true
+ }
}
diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs
index 965e6c77..6b04bacc 100644
--- a/src/dialect/mod.rs
+++ b/src/dialect/mod.rs
@@ -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
diff --git a/src/dialect/postgresql.rs b/src/dialect/postgresql.rs
index 5ce4250f..74b963e8 100644
--- a/src/dialect/postgresql.rs
+++ b/src/dialect/postgresql.rs
@@ -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>> {
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index ca792415..30124bbc 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -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))
}
diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs
index ffcd4e69..b0c215a5 100644
--- a/tests/sqlparser_snowflake.rs
+++ b/tests/sqlparser_snowflake.rs
@@ -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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]