Skip to content

Commit f73c539

Browse files
authored
parser: fix unicode escape idents in cast position (#1127)
1 parent 7a23780 commit f73c539

3 files changed

Lines changed: 74 additions & 3 deletions

File tree

crates/squawk_parser/src/grammar.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn literal(p: &mut Parser<'_>) -> Option<CompletedMarker> {
3737
let m = p.start();
3838
if p.eat(UNICODE_ESC_STRING) {
3939
if p.eat(UESCAPE_KW) {
40-
p.eat(STRING);
40+
p.expect(STRING);
4141
}
4242
}
4343
// E021-03 string continuation syntax
@@ -1678,7 +1678,9 @@ fn path_segment(p: &mut Parser<'_>, kind: SyntaxKind) {
16781678
// skip
16791679
} else if p.at_ts(COL_LABEL_FIRST) {
16801680
let m = p.start();
1681-
p.bump_any();
1681+
if !opt_ident(p) {
1682+
p.bump_any();
1683+
}
16821684
let kind = if p.at(DOT) { NAME_REF } else { kind };
16831685
m.complete(p, kind);
16841686
} else {
@@ -2250,7 +2252,9 @@ fn index_expr(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker {
22502252
fn name_ref_or_index(p: &mut Parser<'_>) {
22512253
assert!(p.at(IDENT) || p.at_ts(TYPE_KEYWORDS) || p.at_ts(ALL_KEYWORDS) || p.at(INT_NUMBER));
22522254
let m = p.start();
2253-
p.bump_any();
2255+
if !opt_ident(p) {
2256+
p.bump_any();
2257+
}
22542258
m.complete(p, NAME_REF);
22552259
}
22562260

@@ -14267,6 +14271,8 @@ fn create_extension(p: &mut Parser<'_>) -> CompletedMarker {
1426714271
}
1426814272

1426914273
fn opt_ident(p: &mut Parser<'_>) -> bool {
14274+
// handle cases like:
14275+
// U&"!0069!006E!0074!0038" UESCAPE '!'
1427014276
if p.eat(IDENT) {
1427114277
if p.eat(UESCAPE_KW) {
1427214278
p.expect(STRING);

crates/squawk_parser/tests/data/ok/select.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,12 @@ ORDER BY sensor_id, day;
509509
select U&"d!0061t!+000061" UESCAPE '!';
510510
SELECT U&' \' UESCAPE '!';
511511
512+
-- select with uescape cast
513+
select 2::U&"!0069!006E!0074!0038" UESCAPE '!' from t;
514+
515+
-- select with uescape on qualified field
516+
select t.U&"!0061" UESCAPE '!' from t;
517+
512518
-- select_from_user_table
513519
select * from user;
514520

crates/squawk_parser/tests/snapshots/tests__select_ok.snap

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6277,6 +6277,65 @@ SOURCE_FILE
62776277
STRING "'!'"
62786278
SEMICOLON ";"
62796279
WHITESPACE "\n\n"
6280+
COMMENT "-- select with uescape cast"
6281+
WHITESPACE "\n"
6282+
SELECT
6283+
SELECT_CLAUSE
6284+
SELECT_KW "select"
6285+
WHITESPACE " "
6286+
TARGET_LIST
6287+
TARGET
6288+
CAST_EXPR
6289+
LITERAL
6290+
INT_NUMBER "2"
6291+
COLON_COLON
6292+
COLON ":"
6293+
COLON ":"
6294+
PATH_TYPE
6295+
PATH
6296+
PATH_SEGMENT
6297+
NAME_REF
6298+
IDENT "U&\"!0069!006E!0074!0038\""
6299+
WHITESPACE " "
6300+
UESCAPE_KW "UESCAPE"
6301+
WHITESPACE " "
6302+
STRING "'!'"
6303+
WHITESPACE " "
6304+
FROM_CLAUSE
6305+
FROM_KW "from"
6306+
WHITESPACE " "
6307+
FROM_ITEM
6308+
NAME_REF
6309+
IDENT "t"
6310+
SEMICOLON ";"
6311+
WHITESPACE "\n\n"
6312+
COMMENT "-- select with uescape on qualified field"
6313+
WHITESPACE "\n"
6314+
SELECT
6315+
SELECT_CLAUSE
6316+
SELECT_KW "select"
6317+
WHITESPACE " "
6318+
TARGET_LIST
6319+
TARGET
6320+
FIELD_EXPR
6321+
NAME_REF
6322+
IDENT "t"
6323+
DOT "."
6324+
NAME_REF
6325+
IDENT "U&\"!0061\""
6326+
WHITESPACE " "
6327+
UESCAPE_KW "UESCAPE"
6328+
WHITESPACE " "
6329+
STRING "'!'"
6330+
WHITESPACE " "
6331+
FROM_CLAUSE
6332+
FROM_KW "from"
6333+
WHITESPACE " "
6334+
FROM_ITEM
6335+
NAME_REF
6336+
IDENT "t"
6337+
SEMICOLON ";"
6338+
WHITESPACE "\n\n"
62806339
COMMENT "-- select_from_user_table"
62816340
WHITESPACE "\n"
62826341
SELECT

0 commit comments

Comments
 (0)