Skip to content

Commit

Permalink
Merge pull request #5370 from andylokandy/fix
Browse files Browse the repository at this point in the history
bugfix(parser): `t`.a should be a column ref
  • Loading branch information
leiysky authored May 14, 2022
2 parents e31a5f3 + f0aeb76 commit fad814e
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 70 deletions.
2 changes: 1 addition & 1 deletion common/ast/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -751,9 +751,9 @@ pub fn expr_element(i: Input) -> IResult<WithSpan> {
| #case : "`CASE ... END`"
| #exists : "`EXISTS (SELECT ...)`"
| #subquery : "`(SELECT ...)`"
| #map_access : "[<key>] | .<key> | :<key>"
| #group
| #column_ref : "<column>"
| #map_access : "[<key>] | .<key> | :<key>"
),
)))(i)?;

Expand Down
4 changes: 2 additions & 2 deletions common/ast/src/parser/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub enum TokenKind {
#[regex(r#"`[^`]*`"#)]
#[regex(r#""([^"\\]|\\.|"")*""#)]
#[regex(r#"'([^'\\]|\\.|'')*'"#)]
QuotedIdent,
QuotedString,

#[regex(r"[xX]'[a-fA-F0-9]*'")]
LiteralHex,
Expand Down Expand Up @@ -608,7 +608,7 @@ impl TokenKind {
!matches!(
self,
Ident
| QuotedIdent
| QuotedString
| LiteralHex
| LiteralNumber
| DoubleEq
Expand Down
41 changes: 28 additions & 13 deletions common/ast/src/parser/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,27 @@ fn non_reserved_identifier(
map(
alt((rule! { Ident }, non_reserved_keyword(is_reserved_keyword))),
|token| Identifier {
span: token.clone(),
name: token.text().to_string(),
quote: None,
span: token.clone(),
},
),
map(rule! { QuotedIdent }, |token| Identifier {
name: token.text()[1..token.text().len() - 1].to_string(),
quote: Some(token.text().chars().next().unwrap()),
span: token.clone(),
}),
move |i| {
match_token(QuotedString)(i).and_then(|(i2, token)| {
if token.text().starts_with('\'') {
Err(nom::Err::Error(Error::from_error_kind(
i,
ErrorKind::ExpectToken(Ident),
)))
} else {
Ok((i2, Identifier {
span: token.clone(),
name: token.text()[1..token.text().len() - 1].to_string(),
quote: Some(token.text().chars().next().unwrap()),
}))
}
})
},
))(i)
}
}
Expand All @@ -119,16 +130,20 @@ fn non_reserved_keyword(
}

pub fn literal_string(i: Input) -> IResult<String> {
map(
rule! {
QuotedIdent
},
|token| token.text()[1..token.text().len() - 1].to_string(),
)(i)
match_token(QuotedString)(i).and_then(|(i2, token)| {
if token.text().starts_with('\'') {
Ok((i2, token.text()[1..token.text().len() - 1].to_string()))
} else {
Err(nom::Err::Error(Error::from_error_kind(
i,
ErrorKind::ExpectToken(QuotedString),
)))
}
})
}

pub fn literal_u64(i: Input) -> IResult<u64> {
rule!(LiteralNumber)(i).and_then(|(i2, token)| {
match_token(LiteralNumber)(i).and_then(|(i2, token)| {
token
.text()
.parse()
Expand Down
1 change: 1 addition & 0 deletions common/ast/tests/it/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ fn test_expr() {
r#"- - + + - 1 + + - 2"#,
r#"1 + a * c.d"#,
r#"number % 2"#,
r#"`t`:k1.k2"#,
r#"col1 not between 1 and 2"#,
r#"sum(col1)"#,
r#""random"()"#,
Expand Down
101 changes: 74 additions & 27 deletions common/ast/tests/it/testdata/expr.txt
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,53 @@ BinaryOp {
}


---------- Input ----------
`t`:k1.k2
---------- Output ---------
`t`:k1.k2
---------- AST ------------
MapAccess {
span: [
Period(6..7),
Ident(7..9),
],
expr: MapAccess {
span: [
Colon(3..4),
Ident(4..6),
],
expr: ColumnRef {
span: [
QuotedString(0..3),
],
database: None,
table: None,
column: Identifier {
name: "t",
quote: Some(
'`',
),
span: QuotedString(0..3),
},
},
accessor: Colon {
key: Identifier {
name: "k1",
quote: None,
span: Ident(4..6),
},
},
},
accessor: Period {
key: Identifier {
name: "k2",
quote: None,
span: Ident(7..9),
},
},
}


---------- Input ----------
col1 not between 1 and 2
---------- Output ---------
Expand Down Expand Up @@ -431,7 +478,7 @@ FunctionCall {
---------- AST ------------
FunctionCall {
span: [
QuotedIdent(0..8),
QuotedString(0..8),
LParen(8..9),
RParen(9..10),
],
Expand All @@ -441,7 +488,7 @@ FunctionCall {
quote: Some(
'"',
),
span: QuotedIdent(0..8),
span: QuotedString(0..8),
},
args: [],
params: [],
Expand Down Expand Up @@ -594,14 +641,14 @@ Trim {
TRIM(0..4),
LParen(4..5),
LEADING(5..12),
QuotedIdent(13..18),
QuotedString(13..18),
FROM(19..23),
QuotedIdent(24..29),
QuotedString(24..29),
RParen(29..30),
],
expr: Literal {
span: [
QuotedIdent(24..29),
QuotedString(24..29),
],
lit: String(
"def",
Expand All @@ -612,7 +659,7 @@ Trim {
Leading,
Literal {
span: [
QuotedIdent(13..18),
QuotedString(13..18),
],
lit: String(
"abc",
Expand Down Expand Up @@ -662,14 +709,14 @@ Position {
span: [
POSITION(0..8),
LParen(8..9),
QuotedIdent(9..12),
QuotedString(9..12),
IN(13..15),
Ident(16..19),
RParen(19..20),
],
substr_expr: Literal {
span: [
QuotedIdent(9..12),
QuotedString(9..12),
],
lit: String(
"a",
Expand Down Expand Up @@ -900,7 +947,7 @@ arr[4]['k']
MapAccess {
span: [
LBracket(6..7),
QuotedIdent(7..10),
QuotedString(7..10),
RBracket(10..11),
],
expr: MapAccess {
Expand Down Expand Up @@ -959,7 +1006,7 @@ BinaryOp {
},
right: Literal {
span: [
QuotedIdent(8..13),
QuotedString(8..13),
],
lit: String(
"^11",
Expand Down Expand Up @@ -1141,7 +1188,7 @@ BinaryOp {
Period(16..17),
Ident(17..23),
Eq(24..25),
QuotedIdent(26..35),
QuotedString(26..35),
THEN(36..40),
Ident(41..50),
ELSE(51..55),
Expand All @@ -1164,7 +1211,7 @@ BinaryOp {
Period(16..17),
Ident(17..23),
Eq(24..25),
QuotedIdent(26..35),
QuotedString(26..35),
THEN(36..40),
Ident(41..50),
ELSE(51..55),
Expand Down Expand Up @@ -1200,7 +1247,7 @@ BinaryOp {
},
right: Literal {
span: [
QuotedIdent(26..35),
QuotedString(26..35),
],
lit: String(
"GERMANY",
Expand Down Expand Up @@ -1441,7 +1488,7 @@ BinaryOp {
},
right: Literal {
span: [
QuotedIdent(48..58),
QuotedString(48..58),
],
lit: String(
"Brand#12",
Expand All @@ -1453,13 +1500,13 @@ BinaryOp {
span: [
IN(87..89),
LParen(90..91),
QuotedIdent(91..100),
QuotedString(91..100),
Comma(100..101),
QuotedIdent(102..110),
QuotedString(102..110),
Comma(110..111),
QuotedIdent(112..121),
QuotedString(112..121),
Comma(121..122),
QuotedIdent(123..131),
QuotedString(123..131),
RParen(131..132),
],
expr: ColumnRef {
Expand All @@ -1477,31 +1524,31 @@ BinaryOp {
list: [
Literal {
span: [
QuotedIdent(91..100),
QuotedString(91..100),
],
lit: String(
"SM CASE",
),
},
Literal {
span: [
QuotedIdent(102..110),
QuotedString(102..110),
],
lit: String(
"SM BOX",
),
},
Literal {
span: [
QuotedIdent(112..121),
QuotedString(112..121),
],
lit: String(
"SM PACK",
),
},
Literal {
span: [
QuotedIdent(123..131),
QuotedString(123..131),
],
lit: String(
"SM PKG",
Expand Down Expand Up @@ -1681,9 +1728,9 @@ BinaryOp {
span: [
IN(332..334),
LParen(335..336),
QuotedIdent(336..341),
QuotedString(336..341),
Comma(341..342),
QuotedIdent(343..352),
QuotedString(343..352),
RParen(352..353),
],
expr: ColumnRef {
Expand All @@ -1701,15 +1748,15 @@ BinaryOp {
list: [
Literal {
span: [
QuotedIdent(336..341),
QuotedString(336..341),
],
lit: String(
"AIR",
),
},
Literal {
span: [
QuotedIdent(343..352),
QuotedString(343..352),
],
lit: String(
"AIR REG",
Expand Down Expand Up @@ -1738,7 +1785,7 @@ BinaryOp {
},
right: Literal {
span: [
QuotedIdent(387..406),
QuotedString(387..406),
],
lit: String(
"DELIVER IN PERSON",
Expand Down
8 changes: 4 additions & 4 deletions common/ast/tests/it/testdata/query-error.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ error:
--> SQL:1:29
|
1 | select * from customer join where a = b
| ^^^^^ expected `(`, `SELECT`, <Ident>, or <QuotedIdent>
| ^^^^^ expected `(`, `SELECT`, <Ident>, or <QuotedString>


---------- Input ----------
Expand All @@ -15,7 +15,7 @@ error:
--> SQL:1:15
|
1 | select * from join customer
| ------ ^^^^ expected `(`, `SELECT`, <Ident>, or <QuotedIdent>
| ------ ^^^^ expected `(`, `SELECT`, <Ident>, or <QuotedString>
| |
| while parsing `SELECT ...`

Expand All @@ -27,7 +27,7 @@ error:
--> SQL:1:30
|
1 | select * from t inner join t1
| ^ expected `(`, `.`, <Ident>, <QuotedIdent>, `AS`, `ON`, or 1 more ...
| ^ expected `(`, `.`, <Ident>, <QuotedString>, `AS`, `ON`, or 1 more ...


---------- Input ----------
Expand All @@ -37,7 +37,7 @@ error:
--> SQL:1:50
|
1 | select * from customer natural inner join orders on a = b
| ^^ expected `(`, `.`, <Ident>, <QuotedIdent>, `AS`, `INNER`, or 12 more ...
| ^^ expected `(`, `.`, <Ident>, <QuotedString>, `AS`, `INNER`, or 12 more ...


---------- Input ----------
Expand Down
Loading

0 comments on commit fad814e

Please sign in to comment.