Skip to content

Commit 07136b7

Browse files
author
Alexander Beedie
committed
Reduce common Vec (re)allocations
1 parent e81eb14 commit 07136b7

1 file changed

Lines changed: 19 additions & 15 deletions

File tree

src/parser/mod.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,7 +1387,7 @@ impl<'a> Parser<'a> {
13871387
debug!("parsing expr");
13881388
let mut expr = self.parse_prefix()?;
13891389

1390-
expr = self.parse_compound_expr(expr, vec![])?;
1390+
expr = self.parse_compound_expr(expr, None)?;
13911391

13921392
debug!("prefix: {expr:?}");
13931393
loop {
@@ -1956,7 +1956,7 @@ impl<'a> Parser<'a> {
19561956
pub fn parse_compound_expr(
19571957
&mut self,
19581958
root: Expr,
1959-
mut chain: Vec<AccessExpr>,
1959+
mut chain: Option<Vec<AccessExpr>>,
19601960
) -> Result<Expr, ParserError> {
19611961
let mut ending_wildcard: Option<TokenWithSpan> = None;
19621962
loop {
@@ -1982,14 +1982,14 @@ impl<'a> Parser<'a> {
19821982
Token::SingleQuotedString(s) => {
19831983
let expr =
19841984
Expr::Identifier(Ident::with_quote_and_span('\'', next_token.span, s));
1985-
chain.push(AccessExpr::Dot(expr));
1985+
chain.get_or_insert_with(Vec::new).push(AccessExpr::Dot(expr));
19861986
self.advance_token(); // The consumed string
19871987
}
19881988
Token::Placeholder(s) => {
19891989
// Snowflake uses $1, $2, etc. for positional column references
19901990
// in staged data queries like: SELECT t.$1 FROM @stage t
19911991
let expr = Expr::Identifier(Ident::with_span(next_token.span, s));
1992-
chain.push(AccessExpr::Dot(expr));
1992+
chain.get_or_insert_with(Vec::new).push(AccessExpr::Dot(expr));
19931993
self.advance_token(); // The consumed placeholder
19941994
}
19951995
// Fallback to parsing an arbitrary expression, but restrict to expression
@@ -2023,20 +2023,23 @@ impl<'a> Parser<'a> {
20232023
// `foo.(bar.baz)` (i.e. a root with an access chain with
20242024
// 1 entry`).
20252025
Some(Expr::CompoundFieldAccess { root, access_chain }) => {
2026-
chain.push(AccessExpr::Dot(*root));
2027-
chain.extend(access_chain);
2026+
let c = chain.get_or_insert_with(Vec::new);
2027+
c.push(AccessExpr::Dot(*root));
2028+
c.extend(access_chain);
2029+
}
2030+
Some(Expr::CompoundIdentifier(parts)) => {
2031+
chain.get_or_insert_with(Vec::new).extend(
2032+
parts.into_iter().map(Expr::Identifier).map(AccessExpr::Dot),
2033+
);
20282034
}
2029-
Some(Expr::CompoundIdentifier(parts)) => chain.extend(
2030-
parts.into_iter().map(Expr::Identifier).map(AccessExpr::Dot),
2031-
),
20322035
Some(expr) => {
2033-
chain.push(AccessExpr::Dot(expr));
2036+
chain.get_or_insert_with(Vec::new).push(AccessExpr::Dot(expr));
20342037
}
20352038
// If the expression is not a valid suffix, fall back to
20362039
// parsing as an identifier. This handles cases like `T.interval`
20372040
// where `interval` is a keyword but should be treated as an identifier.
20382041
None => {
2039-
chain.push(AccessExpr::Dot(Expr::Identifier(
2042+
chain.get_or_insert_with(Vec::new).push(AccessExpr::Dot(Expr::Identifier(
20402043
self.parse_identifier()?,
20412044
)));
20422045
}
@@ -2046,12 +2049,13 @@ impl<'a> Parser<'a> {
20462049
} else if !self.dialect.supports_partiql()
20472050
&& self.peek_token_ref().token == Token::LBracket
20482051
{
2049-
self.parse_multi_dim_subscript(&mut chain)?;
2052+
self.parse_multi_dim_subscript(chain.get_or_insert_with(Vec::new))?;
20502053
} else {
20512054
break;
20522055
}
20532056
}
20542057

2058+
let chain = chain.unwrap_or_default();
20552059
let tok_index = self.get_current_index();
20562060
if let Some(wildcard_token) = ending_wildcard {
20572061
if !Self::is_all_ident(&root, &chain) {
@@ -4898,7 +4902,7 @@ impl<'a> Parser<'a> {
48984902
F: FnMut(&mut Parser<'a>) -> Result<T, ParserError>,
48994903
R: Fn(&Keyword, &mut Parser) -> bool,
49004904
{
4901-
let mut values = vec![];
4905+
let mut values = Vec::with_capacity(8);
49024906
loop {
49034907
values.push(f(self)?);
49044908
if self.is_parse_comma_separated_end_with_trailing_commas(
@@ -4916,7 +4920,7 @@ impl<'a> Parser<'a> {
49164920
where
49174921
F: FnMut(&mut Parser<'a>) -> Result<T, ParserError>,
49184922
{
4919-
let mut values = vec![];
4923+
let mut values = Vec::with_capacity(4);
49204924
loop {
49214925
values.push(f(self)?);
49224926
if !self.consume_token(&Token::Period) {
@@ -4935,7 +4939,7 @@ impl<'a> Parser<'a> {
49354939
where
49364940
F: FnMut(&mut Parser<'a>) -> Result<T, ParserError>,
49374941
{
4938-
let mut values = vec![];
4942+
let mut values = Vec::with_capacity(4);
49394943
loop {
49404944
values.push(f(self)?);
49414945
if !self.parse_keyword(keyword) {

0 commit comments

Comments
 (0)