Skip to content

Commit 97c4d47

Browse files
committed
add support for [*] syntax
1 parent f57af7f commit 97c4d47

File tree

5 files changed

+28
-3
lines changed

5 files changed

+28
-3
lines changed

src/ast/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,10 @@ pub enum JsonPathElem {
519519
///
520520
/// See <https://docs.snowflake.com/en/user-guide/querying-semistructured#bracket-notation>.
521521
Bracket { key: Expr },
522+
/// Accesses all elements in the given (generally array) element. Used for constructs like `foo:bar[*].baz`.
523+
///
524+
/// See <https://docs.databricks.com/aws/en/sql/language-manual/sql-ref-json-path-expression#extract-values-from-arrays>
525+
AllElements,
522526
}
523527

524528
/// A JSON path.
@@ -552,6 +556,9 @@ impl fmt::Display for JsonPath {
552556
JsonPathElem::Bracket { key } => {
553557
write!(f, "[{key}]")?;
554558
}
559+
JsonPathElem::AllElements => {
560+
write!(f, "[*]")?;
561+
}
555562
}
556563
}
557564
Ok(())

src/ast/spans.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,11 +1725,13 @@ impl Spanned for JsonPath {
17251725
///
17261726
/// Missing spans:
17271727
/// - [JsonPathElem::Dot]
1728+
/// - [JsonPathElem::AllElements]
17281729
impl Spanned for JsonPathElem {
17291730
fn span(&self) -> Span {
17301731
match self {
17311732
JsonPathElem::Dot { .. } => Span::empty(),
17321733
JsonPathElem::Bracket { key } => key.span(),
1734+
JsonPathElem::AllElements => Span::empty(),
17331735
}
17341736
}
17351737
}

src/dialect/databricks.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ impl Dialect for DatabricksDialect {
4949
}
5050
}
5151

52+
fn supports_semi_structured_array_all_elements(&self) -> bool {
53+
true
54+
}
55+
5256
fn supports_filter_during_aggregation(&self) -> bool {
5357
true
5458
}

src/dialect/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,11 @@ pub trait Dialect: Debug + Any {
876876
false
877877
}
878878

879+
/// Returns true if the dialect supports writing `[*]` to select all elements in a JSON array.
880+
fn supports_semi_structured_array_all_elements(&self) -> bool {
881+
false
882+
}
883+
879884
/// Returns true if the specified keyword is reserved and cannot be
880885
/// used as an identifier without special handling like quoting.
881886
fn is_reserved_for_identifier(&self, kw: Keyword) -> bool {

src/parser/mod.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3726,10 +3726,17 @@ impl<'a> Parser<'a> {
37263726
path.push(self.parse_json_path_object_key()?);
37273727
}
37283728
Token::LBracket => {
3729-
let key = self.parse_expr()?;
3730-
self.expect_token(&Token::RBracket)?;
3729+
if self.peek_token_ref().token == Token::Mul
3730+
&& self.dialect.supports_semi_structured_array_all_elements()
3731+
{
3732+
self.expect_token(&Token::Mul)?;
3733+
path.push(JsonPathElem::AllElements);
3734+
} else {
3735+
let key = self.parse_expr()?;
3736+
path.push(JsonPathElem::Bracket { key });
3737+
}
37313738

3732-
path.push(JsonPathElem::Bracket { key });
3739+
self.expect_token(&Token::RBracket)?;
37333740
}
37343741
_ => {
37353742
self.prev_token();

0 commit comments

Comments
 (0)