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]

Reply via email to