Skip to content

Commit

Permalink
Improve parsing performance by reducing token cloning (apache#1587)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
davisp and alamb authored Dec 24, 2024
1 parent 024a878 commit df3c565
Showing 6 changed files with 344 additions and 244 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -240,11 +240,14 @@ You can run them with:
```
git checkout main
cd sqlparser_bench
cargo bench
cargo bench -- --save-baseline main
git checkout <your branch>
cargo bench
cargo bench -- --baseline main
```

By adding the `--save-baseline main` and `--baseline main` you can track the
progress of your improvements as you continue working on the feature branch.

## Licensing

All code in this repository is licensed under the [Apache Software License 2.0](LICENSE.txt).
9 changes: 9 additions & 0 deletions src/dialect/mod.rs
Original file line number Diff line number Diff line change
@@ -75,6 +75,15 @@ macro_rules! dialect_of {
};
}

// Similar to above, but for applying directly against an instance of dialect
// instead of a struct member named dialect. This avoids lifetime issues when
// mixing match guards and token references.
macro_rules! dialect_is {
($dialect:ident is $($dialect_type:ty)|+) => {
($($dialect.is::<$dialect_type>())||+)
}
}

/// Encapsulates the differences between SQL implementations.
///
/// # SQL Dialects
8 changes: 4 additions & 4 deletions src/dialect/postgresql.rs
Original file line number Diff line number Diff line change
@@ -245,11 +245,11 @@ impl Dialect for PostgreSqlDialect {

pub fn parse_create(parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
let name = parser.maybe_parse(|parser| -> Result<ObjectName, ParserError> {
parser.expect_keyword(Keyword::CREATE)?;
parser.expect_keyword(Keyword::TYPE)?;
parser.expect_keyword_is(Keyword::CREATE)?;
parser.expect_keyword_is(Keyword::TYPE)?;
let name = parser.parse_object_name(false)?;
parser.expect_keyword(Keyword::AS)?;
parser.expect_keyword(Keyword::ENUM)?;
parser.expect_keyword_is(Keyword::AS)?;
parser.expect_keyword_is(Keyword::ENUM)?;
Ok(name)
});

16 changes: 8 additions & 8 deletions src/dialect/snowflake.rs
Original file line number Diff line number Diff line change
@@ -273,7 +273,7 @@ pub fn parse_create_table(
match &next_token.token {
Token::Word(word) => match word.keyword {
Keyword::COPY => {
parser.expect_keyword(Keyword::GRANTS)?;
parser.expect_keyword_is(Keyword::GRANTS)?;
builder = builder.copy_grants(true);
}
Keyword::COMMENT => {
@@ -297,7 +297,7 @@ pub fn parse_create_table(
break;
}
Keyword::CLUSTER => {
parser.expect_keyword(Keyword::BY)?;
parser.expect_keyword_is(Keyword::BY)?;
parser.expect_token(&Token::LParen)?;
let cluster_by = Some(WrappedCollection::Parentheses(
parser.parse_comma_separated(|p| p.parse_identifier(false))?,
@@ -360,14 +360,14 @@ pub fn parse_create_table(
parser.prev_token();
}
Keyword::AGGREGATION => {
parser.expect_keyword(Keyword::POLICY)?;
parser.expect_keyword_is(Keyword::POLICY)?;
let aggregation_policy = parser.parse_object_name(false)?;
builder = builder.with_aggregation_policy(Some(aggregation_policy));
}
Keyword::ROW => {
parser.expect_keywords(&[Keyword::ACCESS, Keyword::POLICY])?;
let policy = parser.parse_object_name(false)?;
parser.expect_keyword(Keyword::ON)?;
parser.expect_keyword_is(Keyword::ON)?;
parser.expect_token(&Token::LParen)?;
let columns = parser.parse_comma_separated(|p| p.parse_identifier(false))?;
parser.expect_token(&Token::RParen)?;
@@ -536,15 +536,15 @@ pub fn parse_copy_into(parser: &mut Parser) -> Result<Statement, ParserError> {
let from_stage: ObjectName;
let stage_params: StageParamsObject;

parser.expect_keyword(Keyword::FROM)?;
parser.expect_keyword_is(Keyword::FROM)?;
// check if data load transformations are present
match parser.next_token().token {
Token::LParen => {
// data load with transformations
parser.expect_keyword(Keyword::SELECT)?;
parser.expect_keyword_is(Keyword::SELECT)?;
from_transformations = parse_select_items_for_data_load(parser)?;

parser.expect_keyword(Keyword::FROM)?;
parser.expect_keyword_is(Keyword::FROM)?;
from_stage = parse_snowflake_stage_name(parser)?;
stage_params = parse_stage_params(parser)?;

@@ -860,7 +860,7 @@ fn parse_identity_property(parser: &mut Parser) -> Result<IdentityProperty, Pars
))
} else if parser.parse_keyword(Keyword::START) {
let seed = parser.parse_number()?;
parser.expect_keyword(Keyword::INCREMENT)?;
parser.expect_keyword_is(Keyword::INCREMENT)?;
let increment = parser.parse_number()?;

Some(IdentityPropertyFormatKind::StartAndIncrement(
8 changes: 4 additions & 4 deletions src/parser/alter.rs
Original file line number Diff line number Diff line change
@@ -52,11 +52,11 @@ impl Parser<'_> {
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterpolicy.html)
pub fn parse_alter_policy(&mut self) -> Result<Statement, ParserError> {
let name = self.parse_identifier(false)?;
self.expect_keyword(Keyword::ON)?;
self.expect_keyword_is(Keyword::ON)?;
let table_name = self.parse_object_name(false)?;

if self.parse_keyword(Keyword::RENAME) {
self.expect_keyword(Keyword::TO)?;
self.expect_keyword_is(Keyword::TO)?;
let new_name = self.parse_identifier(false)?;
Ok(Statement::AlterPolicy {
name,
@@ -232,7 +232,7 @@ impl Parser<'_> {
Some(Keyword::BYPASSRLS) => RoleOption::BypassRLS(true),
Some(Keyword::NOBYPASSRLS) => RoleOption::BypassRLS(false),
Some(Keyword::CONNECTION) => {
self.expect_keyword(Keyword::LIMIT)?;
self.expect_keyword_is(Keyword::LIMIT)?;
RoleOption::ConnectionLimit(Expr::Value(self.parse_number_value()?))
}
Some(Keyword::CREATEDB) => RoleOption::CreateDB(true),
@@ -256,7 +256,7 @@ impl Parser<'_> {
Some(Keyword::SUPERUSER) => RoleOption::SuperUser(true),
Some(Keyword::NOSUPERUSER) => RoleOption::SuperUser(false),
Some(Keyword::VALID) => {
self.expect_keyword(Keyword::UNTIL)?;
self.expect_keyword_is(Keyword::UNTIL)?;
RoleOption::ValidUntil(Expr::Value(self.parse_value()?))
}
_ => self.expected("option", self.peek_token())?,
Loading

0 comments on commit df3c565

Please sign in to comment.