Skip to content

Commit 988cdbe

Browse files
committed
PartiQl ongoing
1 parent 92be237 commit 988cdbe

17 files changed

+197
-11
lines changed

src/ast/query.rs

+6
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,8 @@ pub enum TableFactor {
974974
with_ordinality: bool,
975975
/// [Partition selection](https://dev.mysql.com/doc/refman/8.0/en/partitioning-selection.html), supported by MySQL.
976976
partitions: Vec<Ident>,
977+
/// Optional PartiQL JsonPath: <https://partiql.org/dql/from.html>
978+
partiql: Option<JsonPath>,
977979
},
978980
Derived {
979981
lateral: bool,
@@ -1375,8 +1377,12 @@ impl fmt::Display for TableFactor {
13751377
version,
13761378
partitions,
13771379
with_ordinality,
1380+
partiql,
13781381
} => {
13791382
write!(f, "{name}")?;
1383+
if let Some(partiql) = partiql {
1384+
write!(f, "{partiql}")?;
1385+
}
13801386
if !partitions.is_empty() {
13811387
write!(f, "PARTITION ({})", display_comma_separated(partitions))?;
13821388
}

src/dialect/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,12 @@ pub trait Dialect: Debug + Any {
680680
fn supports_create_table_select(&self) -> bool {
681681
false
682682
}
683+
684+
/// Returns true if the dialect supports PartiQL for querying semi-structured data
685+
/// <https://partiql.org/index.html>
686+
fn supports_partiql(&self) -> bool {
687+
false
688+
}
683689
}
684690

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

src/dialect/redshift.rs

+5
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,9 @@ impl Dialect for RedshiftSqlDialect {
7474
fn supports_top_before_distinct(&self) -> bool {
7575
true
7676
}
77+
78+
/// Redshift supports PartiQL: <https://docs.aws.amazon.com/redshift/latest/dg/super-overview.html>
79+
fn supports_partiql(&self) -> bool {
80+
true
81+
}
7782
}

src/parser/mod.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -2920,7 +2920,7 @@ impl<'a> Parser<'a> {
29202920
} else if Token::LBracket == tok {
29212921
if dialect_of!(self is PostgreSqlDialect | DuckDbDialect | GenericDialect) {
29222922
self.parse_subscript(expr)
2923-
} else if dialect_of!(self is SnowflakeDialect) {
2923+
} else if dialect_of!(self is SnowflakeDialect) || self.dialect.supports_partiql() {
29242924
self.prev_token();
29252925
self.parse_json_access(expr)
29262926
} else {
@@ -3056,6 +3056,14 @@ impl<'a> Parser<'a> {
30563056
}
30573057

30583058
fn parse_json_access(&mut self, expr: Expr) -> Result<Expr, ParserError> {
3059+
let path = self.parse_json_path()?;
3060+
Ok(Expr::JsonAccess {
3061+
value: Box::new(expr),
3062+
path,
3063+
})
3064+
}
3065+
3066+
fn parse_json_path(&mut self) -> Result<JsonPath, ParserError> {
30593067
let mut path = Vec::new();
30603068
loop {
30613069
match self.next_token().token {
@@ -3079,10 +3087,7 @@ impl<'a> Parser<'a> {
30793087
}
30803088

30813089
debug_assert!(!path.is_empty());
3082-
Ok(Expr::JsonAccess {
3083-
value: Box::new(expr),
3084-
path: JsonPath { path },
3085-
})
3090+
Ok(JsonPath{ path })
30863091
}
30873092

30883093
pub fn parse_map_access(&mut self, expr: Expr) -> Result<Expr, ParserError> {
@@ -10306,7 +10311,12 @@ impl<'a> Parser<'a> {
1030610311
self.parse_open_json_table_factor()
1030710312
} else {
1030810313
let name = self.parse_object_name(true)?;
10309-
10314+
10315+
let partiql = match self.peek_token().token {
10316+
Token::LBracket if self.dialect.supports_partiql() => Some(self.parse_json_path()?),
10317+
_ => None
10318+
};
10319+
1031010320
let partitions: Vec<Ident> = if dialect_of!(self is MySqlDialect | GenericDialect)
1031110321
&& self.parse_keyword(Keyword::PARTITION)
1031210322
{
@@ -10349,6 +10359,7 @@ impl<'a> Parser<'a> {
1034910359
version,
1035010360
partitions,
1035110361
with_ordinality,
10362+
partiql,
1035210363
};
1035310364

1035410365
while let Some(kw) = self.parse_one_of_keywords(&[Keyword::PIVOT, Keyword::UNPIVOT]) {

src/test_utils.rs

+2
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ pub fn table(name: impl Into<String>) -> TableFactor {
345345
version: None,
346346
partitions: vec![],
347347
with_ordinality: false,
348+
partiql: None,
348349
}
349350
}
350351

@@ -360,6 +361,7 @@ pub fn table_with_alias(name: impl Into<String>, alias: impl Into<String>) -> Ta
360361
version: None,
361362
partitions: vec![],
362363
with_ordinality: false,
364+
partiql: None,
363365
}
364366
}
365367

tests/sqlparser_bigquery.rs

+5
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ fn parse_delete_statement() {
229229
version: None,
230230
partitions: vec![],
231231
with_ordinality: false,
232+
partiql: None,
232233
},
233234
from[0].relation
234235
);
@@ -1373,6 +1374,7 @@ fn parse_table_identifiers() {
13731374
version: None,
13741375
partitions: vec![],
13751376
with_ordinality: false,
1377+
partiql: None,
13761378
},
13771379
joins: vec![]
13781380
},]
@@ -1546,6 +1548,7 @@ fn parse_table_time_travel() {
15461548
))),
15471549
partitions: vec![],
15481550
with_ordinality: false,
1551+
partiql: None,
15491552
},
15501553
joins: vec![]
15511554
},]
@@ -1644,6 +1647,7 @@ fn parse_merge() {
16441647
version: Default::default(),
16451648
partitions: Default::default(),
16461649
with_ordinality: false,
1650+
partiql: None,
16471651
},
16481652
table
16491653
);
@@ -1659,6 +1663,7 @@ fn parse_merge() {
16591663
version: Default::default(),
16601664
partitions: Default::default(),
16611665
with_ordinality: false,
1666+
partiql: None,
16621667
},
16631668
source
16641669
);

tests/sqlparser_clickhouse.rs

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ fn parse_map_access_expr() {
6767
version: None,
6868
partitions: vec![],
6969
with_ordinality: false,
70+
partiql: None,
7071
},
7172
joins: vec![],
7273
}],
@@ -172,6 +173,7 @@ fn parse_delimited_identifiers() {
172173
version,
173174
with_ordinality: _,
174175
partitions: _,
176+
partiql: _,
175177
} => {
176178
assert_eq!(vec![Ident::with_quote('"', "a table")], name.0);
177179
assert_eq!(Ident::with_quote('"', "alias"), alias.unwrap().name);

0 commit comments

Comments
 (0)