mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-15 00:09:02 +00:00
Add APIs to reuse token buffers in Tokenizer
(#1094)
This commit is contained in:
parent
b0b62887a2
commit
d72f0a966b
3 changed files with 32 additions and 4 deletions
|
@ -8711,6 +8711,11 @@ impl<'a> Parser<'a> {
|
||||||
self.expect_token(&Token::RParen)?;
|
self.expect_token(&Token::RParen)?;
|
||||||
Ok(partitions)
|
Ok(partitions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Consume the parser and return its underlying token buffer
|
||||||
|
pub fn into_tokens(self) -> Vec<TokenWithLocation> {
|
||||||
|
self.tokens
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Word {
|
impl Word {
|
||||||
|
|
|
@ -543,21 +543,30 @@ impl<'a> Tokenizer<'a> {
|
||||||
|
|
||||||
/// Tokenize the statement and produce a vector of tokens with location information
|
/// Tokenize the statement and produce a vector of tokens with location information
|
||||||
pub fn tokenize_with_location(&mut self) -> Result<Vec<TokenWithLocation>, TokenizerError> {
|
pub fn tokenize_with_location(&mut self) -> Result<Vec<TokenWithLocation>, TokenizerError> {
|
||||||
|
let mut tokens: Vec<TokenWithLocation> = vec![];
|
||||||
|
self.tokenize_with_location_into_buf(&mut tokens)
|
||||||
|
.map(|_| tokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tokenize the statement and append tokens with location information into the provided buffer.
|
||||||
|
/// If an error is thrown, the buffer will contain all tokens that were successfully parsed before the error.
|
||||||
|
pub fn tokenize_with_location_into_buf(
|
||||||
|
&mut self,
|
||||||
|
buf: &mut Vec<TokenWithLocation>,
|
||||||
|
) -> Result<(), TokenizerError> {
|
||||||
let mut state = State {
|
let mut state = State {
|
||||||
peekable: self.query.chars().peekable(),
|
peekable: self.query.chars().peekable(),
|
||||||
line: 1,
|
line: 1,
|
||||||
col: 1,
|
col: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tokens: Vec<TokenWithLocation> = vec![];
|
|
||||||
|
|
||||||
let mut location = state.location();
|
let mut location = state.location();
|
||||||
while let Some(token) = self.next_token(&mut state)? {
|
while let Some(token) = self.next_token(&mut state)? {
|
||||||
tokens.push(TokenWithLocation { token, location });
|
buf.push(TokenWithLocation { token, location });
|
||||||
|
|
||||||
location = state.location();
|
location = state.location();
|
||||||
}
|
}
|
||||||
Ok(tokens)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tokenize the identifer or keywords in `ch`
|
// Tokenize the identifer or keywords in `ch`
|
||||||
|
|
|
@ -31,6 +31,7 @@ use sqlparser::dialect::{
|
||||||
};
|
};
|
||||||
use sqlparser::keywords::ALL_KEYWORDS;
|
use sqlparser::keywords::ALL_KEYWORDS;
|
||||||
use sqlparser::parser::{Parser, ParserError, ParserOptions};
|
use sqlparser::parser::{Parser, ParserError, ParserOptions};
|
||||||
|
use sqlparser::tokenizer::Tokenizer;
|
||||||
use test_utils::{
|
use test_utils::{
|
||||||
all_dialects, alter_table_op, assert_eq_vec, expr_from_projection, join, number, only, table,
|
all_dialects, alter_table_op, assert_eq_vec, expr_from_projection, join, number, only, table,
|
||||||
table_alias, TestedDialects,
|
table_alias, TestedDialects,
|
||||||
|
@ -8080,3 +8081,16 @@ fn test_release_savepoint() {
|
||||||
|
|
||||||
one_statement_parses_to("RELEASE test1", "RELEASE SAVEPOINT test1");
|
one_statement_parses_to("RELEASE test1", "RELEASE SAVEPOINT test1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_buffer_reuse() {
|
||||||
|
let d = GenericDialect {};
|
||||||
|
let q = "INSERT INTO customer WITH foo AS (SELECT 1) SELECT * FROM foo UNION VALUES (1)";
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
Tokenizer::new(&d, q)
|
||||||
|
.tokenize_with_location_into_buf(&mut buf)
|
||||||
|
.unwrap();
|
||||||
|
let mut p = Parser::new(&d).with_tokens_with_locations(buf);
|
||||||
|
p.parse_statements().unwrap();
|
||||||
|
let _ = p.into_tokens();
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue