@@ -3954,6 +3954,26 @@ impl<'a> Parser<'a> {
39543954 })
39553955 }
39563956
3957+ /// Return nth previous token, possibly whitespace
3958+ /// (or [`Token::EOF`] when before the beginning of the stream).
3959+ pub fn peek_prev_nth_token_no_skip(&self, n: usize) -> TokenWithSpan {
3960+ // 0 = next token, -1 = current token, -2 = previous token
3961+ let peek_index = self.index.saturating_sub(1).saturating_sub(n);
3962+ if peek_index == 0 {
3963+ return TokenWithSpan {
3964+ token: Token::EOF,
3965+ span: Span::empty(),
3966+ };
3967+ }
3968+ self.tokens
3969+ .get(peek_index)
3970+ .cloned()
3971+ .unwrap_or(TokenWithSpan {
3972+ token: Token::EOF,
3973+ span: Span::empty(),
3974+ })
3975+ }
3976+
39573977 /// Return true if the next tokens exactly `expected`
39583978 ///
39593979 /// Does not advance the current token.
@@ -4070,16 +4090,13 @@ impl<'a> Parser<'a> {
40704090 )
40714091 }
40724092
4073- /// Look backwards in the token stream and expect that there was only whitespace tokens until the previous newline
4074- pub fn expect_previously_only_whitespace_until_newline(&mut self) -> Result<(), ParserError> {
4075- let mut look_back_count = 2 ;
4093+ /// Look backwards in the token stream and expect that there was only whitespace tokens until the previous newline or beginning of string
4094+ pub(crate) fn expect_previously_only_whitespace_until_newline(&mut self) -> Result<(), ParserError> {
4095+ let mut look_back_count = 1 ;
40764096 loop {
4077- let prev_index = self.index.saturating_sub(look_back_count);
4078- if prev_index == 0 {
4079- break;
4080- }
4081- let prev_token = self.token_at(prev_index);
4097+ let prev_token = self.peek_prev_nth_token_no_skip(look_back_count);
40824098 match prev_token.token {
4099+ Token::EOF => break,
40834100 Token::Whitespace(ref w) => match w {
40844101 Whitespace::Newline => break,
40854102 // special consideration required for single line comments since that string includes the newline
@@ -4091,18 +4108,10 @@ impl<'a> Parser<'a> {
40914108 }
40924109 _ => look_back_count += 1,
40934110 },
4094- _ => {
4095- let current_token = self.get_current_token();
4096- if prev_token == current_token {
4097- // if we are at the start of the statement, we can skip this check
4098- break;
4099- }
4100-
4101- self.expected(
4102- &format!("newline before current token ({})", current_token),
4103- prev_token.clone(),
4104- )?
4105- }
4111+ _ => self.expected(
4112+ &format!("newline before current token ({})", self.get_current_token()),
4113+ prev_token.clone()
4114+ )?,
41064115 };
41074116 }
41084117 Ok(())
@@ -15379,6 +15388,31 @@ mod tests {
1537915388 })
1538015389 }
1538115390
15391+ #[test]
15392+ fn test_peek_prev_nth_token_no_skip() {
15393+ all_dialects().run_parser_method("SELECT 1;\n-- a comment\nRAISERROR('test', 16, 0);", |parser| {
15394+ parser.index = 1;
15395+ assert_eq!(
15396+ parser.peek_prev_nth_token_no_skip(0),
15397+ Token::EOF
15398+ );
15399+ assert_eq!(parser.index, 1);
15400+ parser.index = 7;
15401+ assert_eq!(
15402+ parser.token_at(parser.index - 1).token,
15403+ Token::Word(Word {
15404+ value: "RAISERROR".to_string(),
15405+ quote_style: None,
15406+ keyword: Keyword::RAISERROR,
15407+ })
15408+ );
15409+ assert_eq!(
15410+ parser.peek_prev_nth_token_no_skip(2),
15411+ Token::Whitespace(Whitespace::Newline)
15412+ );
15413+ });
15414+ }
15415+
1538215416 #[cfg(test)]
1538315417 mod test_parse_data_type {
1538415418 use crate::ast::{
0 commit comments