Skip to content

Commit 00455a8

Browse files
author
aleksei.p
committed
Update
1 parent 3f295b8 commit 00455a8

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/dialect/redshift.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl Dialect for RedshiftSqlDialect {
4141
/// treating them as json path. If there is identifier then we assume
4242
/// there is no json path.
4343
fn is_proper_identifier_inside_quotes(&self, mut chars: Peekable<Chars<'_>>) -> bool {
44-
// PartiQL uses square bracket as a start character and a quote is a beginning of quoted identifier
44+
// PartiQL (used as json path query language in Redshift) uses square bracket as a start character and a quote is a beginning of quoted identifier
4545
if let Some(quote_start) = chars.peek() {
4646
if *quote_start == '"' {
4747
return true;
@@ -51,8 +51,9 @@ impl Dialect for RedshiftSqlDialect {
5151
let mut not_white_chars = chars.skip_while(|ch| ch.is_whitespace()).peekable();
5252
if let Some(&ch) = not_white_chars.peek() {
5353
// PartiQL uses single quote as starting identification inside a quote
54-
// It is a normal identifier if it has no single quote at the beginning
55-
return ch != '\'' && self.is_identifier_start(ch);
54+
// It is a normal identifier if it has no single quote at the beginning.
55+
// Additionally square bracket can contain quoted identifier.
56+
return ch == '"' || ch != '\'' && self.is_identifier_start(ch);
5657
}
5758
false
5859
}

tests/sqlparser_redshift.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,31 @@ fn test_redshift_json_path() {
279279
},
280280
expr_from_projection(only(&select.projection))
281281
);
282+
283+
let sql = r#"SELECT db1.sc1.tbl1.col1[0]."id" FROM customer_orders_lineitem"#;
284+
let select = dialects.verified_only_select(sql);
285+
assert_eq!(
286+
&Expr::JsonAccess {
287+
value: Box::new(Expr::CompoundIdentifier(vec![
288+
Ident::new("db1"),
289+
Ident::new("sc1"),
290+
Ident::new("tbl1"),
291+
Ident::new("col1")
292+
])),
293+
path: JsonPath {
294+
path: vec![
295+
JsonPathElem::Bracket {
296+
key: Expr::Value(Value::Number("0".parse().unwrap(), false))
297+
},
298+
JsonPathElem::Dot {
299+
key: "id".to_string(),
300+
quoted: true,
301+
}
302+
]
303+
}
304+
},
305+
expr_from_projection(only(&select.projection))
306+
);
282307
}
283308

284309
#[test]
@@ -357,6 +382,8 @@ fn test_parse_json_path_from() {
357382
#[test]
358383
fn test_parse_select_numbered_columns() {
359384
redshift_and_generic().verified_stmt(r#"SELECT 1 AS "1" FROM a"#);
385+
// RedShift specific case - quoted identifier inside square bracket
386+
redshift().verified_stmt(r#"SELECT 1 AS ["1"] FROM a"#);
360387
}
361388

362389
#[test]

0 commit comments

Comments
 (0)