Skip to content

Commit 36e8ce6

Browse files
alexander-beedieAlexander Beedie
andauthored
Optimise out string allocations and copies in keyword lookup (#2226)
Co-authored-by: Alexander Beedie <alexander.beedie@adia.ae>
1 parent e81eb14 commit 36e8ce6

File tree

2 files changed

+83
-60
lines changed

2 files changed

+83
-60
lines changed

src/parser/mod.rs

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,8 +1618,9 @@ impl<'a> Parser<'a> {
16181618
w: &Word,
16191619
w_span: Span,
16201620
) -> Result<Expr, ParserError> {
1621-
match self.peek_token().token {
1622-
Token::LParen if !self.peek_outer_join_operator() => {
1621+
let is_outer_join = self.peek_outer_join_operator();
1622+
match &self.peek_token_ref().token {
1623+
Token::LParen if !is_outer_join => {
16231624
let id_parts = vec![w.to_ident(w_span)];
16241625
self.parse_function(ObjectName::from(id_parts))
16251626
}
@@ -2244,8 +2245,8 @@ impl<'a> Parser<'a> {
22442245
fn parse_utility_option(&mut self) -> Result<UtilityOption, ParserError> {
22452246
let name = self.parse_identifier()?;
22462247

2247-
let next_token = self.peek_token();
2248-
if next_token == Token::Comma || next_token == Token::RParen {
2248+
let next_token = self.peek_token_ref();
2249+
if next_token == &Token::Comma || next_token == &Token::RParen {
22492250
return Ok(UtilityOption { name, arg: None });
22502251
}
22512252
let arg = self.parse_expr()?;
@@ -2329,7 +2330,7 @@ impl<'a> Parser<'a> {
23292330
/// Parses a single parameter of a lambda function, with optional typing.
23302331
fn parse_lambda_function_parameter(&mut self) -> Result<LambdaFunctionParameter, ParserError> {
23312332
let name = self.parse_identifier()?;
2332-
let data_type = match self.peek_token().token {
2333+
let data_type = match &self.peek_token_ref().token {
23332334
Token::Word(_) => self.maybe_parse(|p| p.parse_data_type())?,
23342335
_ => None,
23352336
};
@@ -2566,7 +2567,7 @@ impl<'a> Parser<'a> {
25662567
let rows = if self.parse_keyword(Keyword::UNBOUNDED) {
25672568
None
25682569
} else {
2569-
Some(Box::new(match self.peek_token().token {
2570+
Some(Box::new(match &self.peek_token_ref().token {
25702571
Token::SingleQuotedString(_) => self.parse_interval()?,
25712572
_ => self.parse_expr()?,
25722573
}))
@@ -3015,7 +3016,7 @@ impl<'a> Parser<'a> {
30153016
Ok(Some(ListAggOnOverflow::Error))
30163017
} else {
30173018
self.expect_keyword_is(Keyword::TRUNCATE)?;
3018-
let filler = match self.peek_token().token {
3019+
let filler = match &self.peek_token_ref().token {
30193020
Token::Word(w)
30203021
if w.keyword == Keyword::WITH || w.keyword == Keyword::WITHOUT =>
30213022
{
@@ -3128,7 +3129,7 @@ impl<'a> Parser<'a> {
31283129
///
31293130
/// Represented in the AST as `Expr::UnaryOp` with `UnaryOperator::Not`.
31303131
pub fn parse_not(&mut self) -> Result<Expr, ParserError> {
3131-
match self.peek_token().token {
3132+
match &self.peek_token_ref().token {
31323133
Token::Word(w) => match w.keyword {
31333134
Keyword::EXISTS => {
31343135
let negated = true;
@@ -3677,7 +3678,7 @@ impl<'a> Parser<'a> {
36773678
trailing_bracket: MatchedTrailingBracket,
36783679
) -> Result<MatchedTrailingBracket, ParserError> {
36793680
let trailing_bracket = if !trailing_bracket.0 {
3680-
match self.peek_token().token {
3681+
match &self.peek_token_ref().token {
36813682
Token::Gt => {
36823683
self.next_token();
36833684
false.into()
@@ -5337,7 +5338,7 @@ impl<'a> Parser<'a> {
53375338

53385339
/// Parse 'AS' before as query,such as `WITH XXX AS SELECT XXX` oer `CACHE TABLE AS SELECT XXX`
53395340
pub fn parse_as_query(&mut self) -> Result<(bool, Box<Query>), ParserError> {
5340-
match self.peek_token().token {
5341+
match &self.peek_token_ref().token {
53415342
Token::Word(word) => match word.keyword {
53425343
Keyword::AS => {
53435344
self.next_token();
@@ -5854,7 +5855,7 @@ impl<'a> Parser<'a> {
58545855
}
58555856
_ => parser_err!(
58565857
"Expected table column definitions after TABLE keyword",
5857-
p.peek_token().span.start
5858+
p.peek_token_ref().span.start
58585859
)?,
58595860
};
58605861

@@ -7499,7 +7500,7 @@ impl<'a> Parser<'a> {
74997500
pub fn parse_big_query_declare(&mut self) -> Result<Statement, ParserError> {
75007501
let names = self.parse_comma_separated(Parser::parse_identifier)?;
75017502

7502-
let data_type = match self.peek_token().token {
7503+
let data_type = match &self.peek_token_ref().token {
75037504
Token::Word(w) if w.keyword == Keyword::DEFAULT => None,
75047505
_ => Some(self.parse_data_type()?),
75057506
};
@@ -7563,7 +7564,7 @@ impl<'a> Parser<'a> {
75637564
let (declare_type, for_query, assigned_expr, data_type) =
75647565
if self.parse_keyword(Keyword::CURSOR) {
75657566
self.expect_keyword_is(Keyword::FOR)?;
7566-
match self.peek_token().token {
7567+
match &self.peek_token_ref().token {
75677568
Token::Word(w) if w.keyword == Keyword::SELECT => (
75687569
Some(DeclareType::Cursor),
75697570
Some(self.parse_query()?),
@@ -7626,7 +7627,7 @@ impl<'a> Parser<'a> {
76267627

76277628
stmts.push(stmt);
76287629
if self.consume_token(&Token::SemiColon) {
7629-
match self.peek_token().token {
7630+
match &self.peek_token_ref().token {
76307631
Token::Word(w)
76317632
if ALL_KEYWORDS
76327633
.binary_search(&w.value.to_uppercase().as_str())
@@ -7680,7 +7681,7 @@ impl<'a> Parser<'a> {
76807681
let ident = self.parse_identifier()?;
76817682
if !ident.value.starts_with('@')
76827683
&& !matches!(
7683-
self.peek_token().token,
7684+
&self.peek_token_ref().token,
76847685
Token::Word(w) if w.keyword == Keyword::CURSOR
76857686
)
76867687
{
@@ -7692,7 +7693,7 @@ impl<'a> Parser<'a> {
76927693
}
76937694
}?;
76947695

7695-
let (declare_type, data_type) = match self.peek_token().token {
7696+
let (declare_type, data_type) = match &self.peek_token_ref().token {
76967697
Token::Word(w) => match w.keyword {
76977698
Keyword::CURSOR => {
76987699
self.next_token();
@@ -7739,7 +7740,7 @@ impl<'a> Parser<'a> {
77397740
pub fn parse_snowflake_variable_declaration_expression(
77407741
&mut self,
77417742
) -> Result<Option<DeclareAssignment>, ParserError> {
7742-
Ok(match self.peek_token().token {
7743+
Ok(match &self.peek_token_ref().token {
77437744
Token::Word(w) if w.keyword == Keyword::DEFAULT => {
77447745
self.next_token(); // Skip `DEFAULT`
77457746
Some(DeclareAssignment::Default(Box::new(self.parse_expr()?)))
@@ -7763,7 +7764,7 @@ impl<'a> Parser<'a> {
77637764
pub fn parse_mssql_variable_declaration_expression(
77647765
&mut self,
77657766
) -> Result<Option<DeclareAssignment>, ParserError> {
7766-
Ok(match self.peek_token().token {
7767+
Ok(match &self.peek_token_ref().token {
77677768
Token::Eq => {
77687769
self.next_token(); // Skip `=`
77697770
Some(DeclareAssignment::MsSqlAssignment(Box::new(
@@ -8457,7 +8458,7 @@ impl<'a> Parser<'a> {
84578458
} else {
84588459
parser_err!(
84598460
"Expecting DELETE ROWS, PRESERVE ROWS or DROP",
8460-
self.peek_token()
8461+
self.peek_token_ref()
84618462
)
84628463
}
84638464
}
@@ -9602,7 +9603,7 @@ impl<'a> Parser<'a> {
96029603
{
96039604
let display_as_key = w.keyword == Keyword::KEY;
96049605

9605-
let name = match self.peek_token().token {
9606+
let name = match &self.peek_token_ref().token {
96069607
Token::Word(word) if word.keyword == Keyword::USING => None,
96079608
_ => self.parse_optional_ident()?,
96089609
};
@@ -9803,7 +9804,7 @@ impl<'a> Parser<'a> {
98039804
pub fn parse_sql_option(&mut self) -> Result<SqlOption, ParserError> {
98049805
let is_mssql = dialect_of!(self is MsSqlDialect|GenericDialect);
98059806

9806-
match self.peek_token().token {
9807+
match &self.peek_token_ref().token {
98079808
Token::Word(w) if w.keyword == Keyword::HEAP && is_mssql => {
98089809
Ok(SqlOption::Ident(self.parse_identifier()?))
98099810
}
@@ -11740,7 +11741,7 @@ impl<'a> Parser<'a> {
1174011741
if trailing_bracket.0 {
1174111742
return parser_err!(
1174211743
format!("unmatched > after parsing data type {ty}"),
11743-
self.peek_token()
11744+
self.peek_token_ref()
1174411745
);
1174511746
}
1174611747

@@ -15172,7 +15173,7 @@ impl<'a> Parser<'a> {
1517215173
}
1517315174
} else {
1517415175
let natural = self.parse_keyword(Keyword::NATURAL);
15175-
let peek_keyword = if let Token::Word(w) = self.peek_token().token {
15176+
let peek_keyword = if let Token::Word(w) = &self.peek_token_ref().token {
1517615177
w.keyword
1517715178
} else {
1517815179
Keyword::NoKeyword
@@ -15549,7 +15550,7 @@ impl<'a> Parser<'a> {
1554915550
} else {
1555015551
let name = self.parse_object_name(true)?;
1555115552

15552-
let json_path = match self.peek_token().token {
15553+
let json_path = match &self.peek_token_ref().token {
1555315554
Token::LBracket if self.dialect.supports_partiql() => Some(self.parse_json_path()?),
1555415555
_ => None,
1555515556
};
@@ -15953,12 +15954,13 @@ impl<'a> Parser<'a> {
1595315954
}
1595415955
where_clause = Some(self.parse_expr()?);
1595515956
} else {
15957+
let tok = self.peek_token_ref();
1595615958
return parser_err!(
1595715959
format!(
1595815960
"Expected one of DIMENSIONS, METRICS, FACTS or WHERE, got {}",
15959-
self.peek_token().token
15961+
tok.token
1596015962
),
15961-
self.peek_token_ref().span.start
15963+
tok.span.start
1596215964
)?;
1596315965
}
1596415966
}
@@ -18979,7 +18981,7 @@ impl<'a> Parser<'a> {
1897918981

1898018982
/// Parse a window specification.
1898118983
pub fn parse_window_spec(&mut self) -> Result<WindowSpec, ParserError> {
18982-
let window_name = match self.peek_token().token {
18984+
let window_name = match &self.peek_token_ref().token {
1898318985
Token::Word(word) if word.keyword == Keyword::NoKeyword => {
1898418986
self.parse_optional_ident()?
1898518987
}
@@ -19277,9 +19279,9 @@ impl<'a> Parser<'a> {
1927719279
Some(Keyword::DOUBLE) => Ok(UserDefinedTypeSqlDefinitionOption::Alignment(
1927819280
Alignment::Double,
1927919281
)),
19280-
_ => self.expected(
19282+
_ => self.expected_ref(
1928119283
"alignment value (char, int2, int4, or double)",
19282-
self.peek_token(),
19284+
self.peek_token_ref(),
1928319285
),
1928419286
}
1928519287
}
@@ -19304,9 +19306,9 @@ impl<'a> Parser<'a> {
1930419306
Some(Keyword::MAIN) => Ok(UserDefinedTypeSqlDefinitionOption::Storage(
1930519307
UserDefinedTypeStorage::Main,
1930619308
)),
19307-
_ => self.expected(
19309+
_ => self.expected_ref(
1930819310
"storage value (plain, external, extended, or main)",
19309-
self.peek_token(),
19311+
self.peek_token_ref(),
1931019312
),
1931119313
}
1931219314
}
@@ -19645,9 +19647,9 @@ impl<'a> Parser<'a> {
1964519647
break;
1964619648
}
1964719649
_ => {
19648-
return self.expected(
19650+
return self.expected_ref(
1964919651
"another option, EOF, SemiColon, Comma or ')'",
19650-
self.peek_token(),
19652+
self.peek_token_ref(),
1965119653
)
1965219654
}
1965319655
};

0 commit comments

Comments
 (0)