Skip to content

Commit b57c60a

Browse files
committed
Only use parse_expr() when we expect an expression (0/4)
Before this commit there was a single `parse_expr(u8)` method, which was called both 1) from within the expression parser (to parse subexpression consisting of operators with higher priority than the current one), and 2) from the top-down parser both a) to parse true expressions (such as an item of the SELECT list or the condition after WHERE or after ON), and b) to parse sequences which are not exactly "expressions". This starts cleaning this up by renaming the `parse_expr(u8)` method to `parse_subexpr()` and using it only for (1) - i.e. usually providing a non-zero precedence parameter. The non-intuitively called `parse()` method is renamed to `parse_expr()`, which became available and is used for (2a). While reviewing the existing callers of `parse_expr`, four points to follow up on were identified (marked "TBD (#)" in the commit): 1) Do not lose parens (e.g. `(1+2)*3`) when roundtripping String->AST->String by using SQLNested. 2) Incorrect precedence of the NOT unary 3) `parse_table_factor` accepts any expression where a SELECT subquery is expected. 4) parse_delete uses parse_expr() to retrieve a table name These are dealt with in the commits to follow.
1 parent 707c58a commit b57c60a

File tree

4 files changed

+23
-23
lines changed

4 files changed

+23
-23
lines changed

src/sqlparser.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ impl Parser {
109109
}
110110

111111
/// Parse a new expression
112-
pub fn parse(&mut self) -> Result<ASTNode, ParserError> {
113-
self.parse_expr(0)
112+
pub fn parse_expr(&mut self) -> Result<ASTNode, ParserError> {
113+
self.parse_subexpr(0)
114114
}
115115

116116
/// Parse tokens until the precedence changes
117-
pub fn parse_expr(&mut self, precedence: u8) -> Result<ASTNode, ParserError> {
117+
pub fn parse_subexpr(&mut self, precedence: u8) -> Result<ASTNode, ParserError> {
118118
debug!("parsing expr");
119119
let mut expr = self.parse_prefix()?;
120120
debug!("prefix: {:?}", expr);
@@ -167,7 +167,7 @@ impl Parser {
167167
"CAST" => self.parse_cast_expression(),
168168
"NOT" => Ok(ASTNode::SQLUnary {
169169
operator: SQLOperator::Not,
170-
expr: Box::new(self.parse_expr(0)?),
170+
expr: Box::new(self.parse_subexpr(0)?), // TBD (2)
171171
}),
172172
_ => match self.peek_token() {
173173
Some(Token::LParen) => self.parse_function(&w.value),
@@ -194,7 +194,7 @@ impl Parser {
194194
self.parse_sql_value()
195195
}
196196
Token::LParen => {
197-
let expr = self.parse();
197+
let expr = self.parse_expr(); // TBD (1)
198198
self.expect_token(&Token::RParen)?;
199199
expr
200200
}
@@ -230,11 +230,11 @@ impl Parser {
230230
let mut results = vec![];
231231
let mut else_result = None;
232232
loop {
233-
conditions.push(self.parse_expr(0)?);
233+
conditions.push(self.parse_expr()?);
234234
self.expect_keyword("THEN")?;
235-
results.push(self.parse_expr(0)?);
235+
results.push(self.parse_expr()?);
236236
if self.parse_keywords(vec!["ELSE"]) {
237-
else_result = Some(Box::new(self.parse_expr(0)?));
237+
else_result = Some(Box::new(self.parse_expr()?));
238238
if self.parse_keywords(vec!["END"]) {
239239
break;
240240
} else {
@@ -261,7 +261,7 @@ impl Parser {
261261
/// Parse a SQL CAST function e.g. `CAST(expr AS FLOAT)`
262262
pub fn parse_cast_expression(&mut self) -> Result<ASTNode, ParserError> {
263263
self.expect_token(&Token::LParen)?;
264-
let expr = self.parse_expr(0)?;
264+
let expr = self.parse_expr()?;
265265
self.expect_keyword("AS")?;
266266
let data_type = self.parse_data_type()?;
267267
self.expect_token(&Token::RParen)?;
@@ -298,7 +298,7 @@ impl Parser {
298298
Ok(ASTNode::SQLBinaryExpr {
299299
left: Box::new(expr),
300300
op: SQLOperator::NotLike,
301-
right: Box::new(self.parse_expr(precedence)?),
301+
right: Box::new(self.parse_subexpr(precedence)?),
302302
})
303303
} else {
304304
parser_err!("Invalid tokens after NOT")
@@ -322,12 +322,12 @@ impl Parser {
322322
| Token::Div => Ok(ASTNode::SQLBinaryExpr {
323323
left: Box::new(expr),
324324
op: self.to_sql_operator(&tok)?,
325-
right: Box::new(self.parse_expr(precedence)?),
325+
right: Box::new(self.parse_subexpr(precedence)?),
326326
}),
327327
_ => parser_err!(format!("No infix parser for token {:?}", tok)),
328328
},
329329
// This is not supposed to happen, because of the precedence check
330-
// in parse_expr.
330+
// in parse_subexpr.
331331
None => parser_err!("Unexpected EOF in parse_infix"),
332332
}
333333
}
@@ -1106,13 +1106,13 @@ impl Parser {
11061106

11071107
pub fn parse_delete(&mut self) -> Result<SQLStatement, ParserError> {
11081108
let relation: Option<Box<ASTNode>> = if self.parse_keyword("FROM") {
1109-
Some(Box::new(self.parse_expr(0)?))
1109+
Some(Box::new(self.parse_subexpr(0)?)) /* TBD (4) */
11101110
} else {
11111111
None
11121112
};
11131113

11141114
let selection = if self.parse_keyword("WHERE") {
1115-
Some(Box::new(self.parse_expr(0)?))
1115+
Some(Box::new(self.parse_expr()?))
11161116
} else {
11171117
None
11181118
};
@@ -1136,7 +1136,7 @@ impl Parser {
11361136
};
11371137

11381138
let selection = if self.parse_keyword("WHERE") {
1139-
let expr = self.parse_expr(0)?;
1139+
let expr = self.parse_expr()?;
11401140
Some(Box::new(expr))
11411141
} else {
11421142
None
@@ -1149,7 +1149,7 @@ impl Parser {
11491149
};
11501150

11511151
let having = if self.parse_keyword("HAVING") {
1152-
Some(Box::new(self.parse_expr(0)?))
1152+
Some(Box::new(self.parse_expr()?))
11531153
} else {
11541154
None
11551155
};
@@ -1182,7 +1182,7 @@ impl Parser {
11821182
pub fn parse_table_factor(&mut self) -> Result<ASTNode, ParserError> {
11831183
let relation = if self.consume_token(&Token::LParen) {
11841184
self.prev_token();
1185-
self.parse_expr(0)?
1185+
self.parse_subexpr(0)? /* TBD (3) */
11861186
} else {
11871187
self.parse_compound_identifier(&Token::Period)?
11881188
};
@@ -1197,7 +1197,7 @@ impl Parser {
11971197
if natural {
11981198
Ok(JoinConstraint::Natural)
11991199
} else if self.parse_keyword("ON") {
1200-
let constraint = self.parse_expr(0)?;
1200+
let constraint = self.parse_expr()?;
12011201
Ok(JoinConstraint::On(constraint))
12021202
} else if self.parse_keyword("USING") {
12031203
self.expect_token(&Token::LParen)?;
@@ -1338,7 +1338,7 @@ impl Parser {
13381338
pub fn parse_expr_list(&mut self) -> Result<Vec<ASTNode>, ParserError> {
13391339
let mut expr_list: Vec<ASTNode> = vec![];
13401340
loop {
1341-
expr_list.push(self.parse_expr(0)?);
1341+
expr_list.push(self.parse_expr()?);
13421342
if let Some(t) = self.peek_token() {
13431343
if t == Token::Comma {
13441344
self.next_token();
@@ -1357,7 +1357,7 @@ impl Parser {
13571357
pub fn parse_order_by_expr_list(&mut self) -> Result<Vec<SQLOrderByExpr>, ParserError> {
13581358
let mut expr_list: Vec<SQLOrderByExpr> = vec![];
13591359
loop {
1360-
let expr = self.parse_expr(0)?;
1360+
let expr = self.parse_expr()?;
13611361

13621362
let asc = if self.parse_keyword("ASC") {
13631363
Some(true)

tests/sqlparser_ansi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ fn parse_sql_expr(sql: &str) -> ASTNode {
2323
let mut tokenizer = Tokenizer::new(&dialect, &sql);
2424
let tokens = tokenizer.tokenize().unwrap();
2525
let mut parser = Parser::new(tokens);
26-
let ast = parser.parse().unwrap();
26+
let ast = parser.parse_expr().unwrap();
2727
ast
2828
}

tests/sqlparser_generic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,6 @@ fn parse_sql_expr_with(dialect: &Dialect, sql: &str) -> ASTNode {
734734
let mut tokenizer = Tokenizer::new(dialect, &sql);
735735
let tokens = tokenizer.tokenize().unwrap();
736736
let mut parser = Parser::new(tokens);
737-
let ast = parser.parse().unwrap();
737+
let ast = parser.parse_expr().unwrap();
738738
ast
739739
}

tests/sqlparser_postgres.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ fn parse_sql_statements(sql: &str) -> Result<Vec<SQLStatement>, ParserError> {
389389
fn parse_sql_expr(sql: &str) -> ASTNode {
390390
debug!("sql: {}", sql);
391391
let mut parser = parser(sql);
392-
let ast = parser.parse().unwrap();
392+
let ast = parser.parse_expr().unwrap();
393393
ast
394394
}
395395

0 commit comments

Comments
 (0)