Immutable parser (Tokenize borrow strings cont) (#2098)
Some checks failed
Rust / codestyle (push) Has been cancelled
Rust / lint (push) Has been cancelled
Rust / benchmark-lint (push) Has been cancelled
Rust / compile (push) Has been cancelled
Rust / docs (push) Has been cancelled
Rust / compile-no-std (push) Has been cancelled
Rust / test (beta) (push) Has been cancelled
Rust / test (nightly) (push) Has been cancelled
Rust / test (stable) (push) Has been cancelled

Co-authored-by: Eyal Leshem <eyal@satoricyber.com>
This commit is contained in:
eyalleshem 2025-12-18 06:27:50 +02:00 committed by GitHub
parent b098976cab
commit c6933bb8ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 658 additions and 716 deletions

View file

@ -2790,7 +2790,7 @@ impl fmt::Display for Declare {
}
/// Sql options of a `CREATE TABLE` statement.
#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CreateTableOptions {

View file

@ -2407,7 +2407,7 @@ pub mod tests {
#[test]
fn test_join() {
let dialect = &GenericDialect;
let mut test = SpanTest::new(
let test = SpanTest::new(
dialect,
"SELECT id, name FROM users LEFT JOIN companies ON users.company_id = companies.id",
);
@ -2432,7 +2432,7 @@ pub mod tests {
#[test]
pub fn test_union() {
let dialect = &GenericDialect;
let mut test = SpanTest::new(
let test = SpanTest::new(
dialect,
"SELECT a FROM postgres.public.source UNION SELECT a FROM postgres.public.source",
);
@ -2449,7 +2449,7 @@ pub mod tests {
#[test]
pub fn test_subquery() {
let dialect = &GenericDialect;
let mut test = SpanTest::new(
let test = SpanTest::new(
dialect,
"SELECT a FROM (SELECT a FROM postgres.public.source) AS b",
);
@ -2474,7 +2474,7 @@ pub mod tests {
#[test]
pub fn test_cte() {
let dialect = &GenericDialect;
let mut test = SpanTest::new(dialect, "WITH cte_outer AS (SELECT a FROM postgres.public.source), cte_ignored AS (SELECT a FROM cte_outer), cte_inner AS (SELECT a FROM cte_outer) SELECT a FROM cte_inner");
let test = SpanTest::new(dialect, "WITH cte_outer AS (SELECT a FROM postgres.public.source), cte_ignored AS (SELECT a FROM cte_outer), cte_inner AS (SELECT a FROM cte_outer) SELECT a FROM cte_inner");
let query = test.0.parse_query().unwrap();
@ -2486,7 +2486,7 @@ pub mod tests {
#[test]
pub fn test_snowflake_lateral_flatten() {
let dialect = &SnowflakeDialect;
let mut test = SpanTest::new(dialect, "SELECT FLATTENED.VALUE:field::TEXT AS FIELD FROM SNOWFLAKE.SCHEMA.SOURCE AS S, LATERAL FLATTEN(INPUT => S.JSON_ARRAY) AS FLATTENED");
let test = SpanTest::new(dialect, "SELECT FLATTENED.VALUE:field::TEXT AS FIELD FROM SNOWFLAKE.SCHEMA.SOURCE AS S, LATERAL FLATTEN(INPUT => S.JSON_ARRAY) AS FLATTENED");
let query = test.0.parse_select().unwrap();
@ -2498,7 +2498,7 @@ pub mod tests {
#[test]
pub fn test_wildcard_from_cte() {
let dialect = &GenericDialect;
let mut test = SpanTest::new(
let test = SpanTest::new(
dialect,
"WITH cte AS (SELECT a FROM postgres.public.source) SELECT cte.* FROM cte",
);
@ -2524,7 +2524,7 @@ pub mod tests {
#[test]
fn test_case_expr_span() {
let dialect = &GenericDialect;
let mut test = SpanTest::new(dialect, "CASE 1 WHEN 2 THEN 3 ELSE 4 END");
let test = SpanTest::new(dialect, "CASE 1 WHEN 2 THEN 3 ELSE 4 END");
let expr = test.0.parse_expr().unwrap();
let expr_span = expr.span();
assert_eq!(

View file

@ -46,7 +46,7 @@ const RESERVED_FOR_COLUMN_ALIAS: &[Keyword] = &[
pub struct BigQueryDialect;
impl Dialect for BigQueryDialect {
fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
fn parse_statement(&self, parser: &Parser) -> Option<Result<Statement, ParserError>> {
if parser.parse_keyword(Keyword::BEGIN) {
if parser.peek_keyword(Keyword::TRANSACTION)
|| parser.peek_token_ref().token == Token::SemiColon
@ -145,7 +145,7 @@ impl Dialect for BigQueryDialect {
true
}
fn is_column_alias(&self, kw: &Keyword, _parser: &mut Parser) -> bool {
fn is_column_alias(&self, kw: &Keyword, _parser: &Parser) -> bool {
!RESERVED_FOR_COLUMN_ALIAS.contains(kw)
}

View file

@ -466,7 +466,7 @@ pub trait Dialect: Debug + Any {
}
/// Dialect-specific prefix parser override
fn parse_prefix(&self, _parser: &mut Parser) -> Option<Result<Expr, ParserError>> {
fn parse_prefix(&self, _parser: &Parser) -> Option<Result<Expr, ParserError>> {
// return None to fall back to the default behavior
None
}
@ -615,7 +615,7 @@ pub trait Dialect: Debug + Any {
/// If `None` is returned, falls back to the default behavior.
fn parse_infix(
&self,
_parser: &mut Parser,
_parser: &Parser,
_expr: &Expr,
_precedence: u8,
) -> Option<Result<Expr, ParserError>> {
@ -778,7 +778,7 @@ pub trait Dialect: Debug + Any {
/// This method is called to parse the next statement.
///
/// If `None` is returned, falls back to the default behavior.
fn parse_statement(&self, _parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
fn parse_statement(&self, _parser: &Parser) -> Option<Result<Statement, ParserError>> {
// return None to fall back to the default behavior
None
}
@ -790,7 +790,7 @@ pub trait Dialect: Debug + Any {
/// If `None` is returned, falls back to the default behavior.
fn parse_column_option(
&self,
_parser: &mut Parser,
_parser: &Parser,
) -> Result<Option<Result<Option<ColumnOption>, ParserError>>, ParserError> {
// return None to fall back to the default behavior
Ok(None)
@ -1021,33 +1021,33 @@ pub trait Dialect: Debug + Any {
/// Returns true if the specified keyword should be parsed as a column identifier.
/// See [keywords::RESERVED_FOR_COLUMN_ALIAS]
fn is_column_alias(&self, kw: &Keyword, _parser: &mut Parser) -> bool {
fn is_column_alias(&self, kw: &Keyword, _parser: &Parser) -> bool {
!keywords::RESERVED_FOR_COLUMN_ALIAS.contains(kw)
}
/// Returns true if the specified keyword should be parsed as a select item alias.
/// When explicit is true, the keyword is preceded by an `AS` word. Parser is provided
/// to enable looking ahead if needed.
fn is_select_item_alias(&self, explicit: bool, kw: &Keyword, parser: &mut Parser) -> bool {
fn is_select_item_alias(&self, explicit: bool, kw: &Keyword, parser: &Parser) -> bool {
explicit || self.is_column_alias(kw, parser)
}
/// Returns true if the specified keyword should be parsed as a table factor identifier.
/// See [keywords::RESERVED_FOR_TABLE_FACTOR]
fn is_table_factor(&self, kw: &Keyword, _parser: &mut Parser) -> bool {
fn is_table_factor(&self, kw: &Keyword, _parser: &Parser) -> bool {
!keywords::RESERVED_FOR_TABLE_FACTOR.contains(kw)
}
/// Returns true if the specified keyword should be parsed as a table factor alias.
/// See [keywords::RESERVED_FOR_TABLE_ALIAS]
fn is_table_alias(&self, kw: &Keyword, _parser: &mut Parser) -> bool {
fn is_table_alias(&self, kw: &Keyword, _parser: &Parser) -> bool {
!keywords::RESERVED_FOR_TABLE_ALIAS.contains(kw)
}
/// Returns true if the specified keyword should be parsed as a table factor alias.
/// When explicit is true, the keyword is preceded by an `AS` word. Parser is provided
/// to enable looking ahead if needed.
fn is_table_factor_alias(&self, explicit: bool, kw: &Keyword, parser: &mut Parser) -> bool {
fn is_table_factor_alias(&self, explicit: bool, kw: &Keyword, parser: &Parser) -> bool {
explicit || self.is_table_alias(kw, parser)
}
@ -1400,14 +1400,14 @@ mod tests {
fn parse_prefix(
&self,
parser: &mut sqlparser::parser::Parser,
parser: &sqlparser::parser::Parser,
) -> Option<Result<Expr, sqlparser::parser::ParserError>> {
self.0.parse_prefix(parser)
}
fn parse_infix(
&self,
parser: &mut sqlparser::parser::Parser,
parser: &sqlparser::parser::Parser,
expr: &Expr,
precedence: u8,
) -> Option<Result<Expr, sqlparser::parser::ParserError>> {
@ -1423,7 +1423,7 @@ mod tests {
fn parse_statement(
&self,
parser: &mut sqlparser::parser::Parser,
parser: &sqlparser::parser::Parser,
) -> Option<Result<Statement, sqlparser::parser::ParserError>> {
self.0.parse_statement(parser)
}

View file

@ -128,11 +128,11 @@ impl Dialect for MsSqlDialect {
&[GranteesType::Public]
}
fn is_column_alias(&self, kw: &Keyword, _parser: &mut Parser) -> bool {
fn is_column_alias(&self, kw: &Keyword, _parser: &Parser) -> bool {
!keywords::RESERVED_FOR_COLUMN_ALIAS.contains(kw) && !RESERVED_FOR_COLUMN_ALIAS.contains(kw)
}
fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
fn parse_statement(&self, parser: &Parser) -> Option<Result<Statement, ParserError>> {
if parser.peek_keyword(Keyword::IF) {
Some(self.parse_if_stmt(parser))
} else if parser.parse_keywords(&[Keyword::CREATE, Keyword::TRIGGER]) {
@ -157,7 +157,7 @@ impl MsSqlDialect {
/// [ ELSE
/// { sql_statement | statement_block } ]
/// ```
fn parse_if_stmt(&self, parser: &mut Parser) -> Result<Statement, ParserError> {
fn parse_if_stmt(&self, parser: &Parser) -> Result<Statement, ParserError> {
let if_token = parser.expect_keyword(Keyword::IF)?;
let condition = parser.parse_expr()?;
@ -240,7 +240,7 @@ impl MsSqlDialect {
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql
fn parse_create_trigger(
&self,
parser: &mut Parser,
parser: &Parser,
or_alter: bool,
) -> Result<Statement, ParserError> {
let name = parser.parse_object_name(false)?;
@ -279,7 +279,7 @@ impl MsSqlDialect {
/// Stops parsing when reaching EOF or the given keyword.
fn parse_statement_list(
&self,
parser: &mut Parser,
parser: &Parser,
terminal_keyword: Option<Keyword>,
) -> Result<Vec<Statement>, ParserError> {
let mut stmts = Vec::new();

View file

@ -86,7 +86,7 @@ impl Dialect for MySqlDialect {
fn parse_infix(
&self,
parser: &mut crate::parser::Parser,
parser: &crate::parser::Parser,
expr: &crate::ast::Expr,
_precedence: u8,
) -> Option<Result<crate::ast::Expr, ParserError>> {
@ -102,7 +102,7 @@ impl Dialect for MySqlDialect {
}
}
fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
fn parse_statement(&self, parser: &Parser) -> Option<Result<Statement, ParserError>> {
if parser.parse_keywords(&[Keyword::LOCK, Keyword::TABLES]) {
Some(parse_lock_tables(parser))
} else if parser.parse_keywords(&[Keyword::UNLOCK, Keyword::TABLES]) {
@ -134,7 +134,7 @@ impl Dialect for MySqlDialect {
true
}
fn is_table_factor_alias(&self, explicit: bool, kw: &Keyword, _parser: &mut Parser) -> bool {
fn is_table_factor_alias(&self, explicit: bool, kw: &Keyword, _parser: &Parser) -> bool {
explicit
|| (!keywords::RESERVED_FOR_TABLE_ALIAS.contains(kw)
&& !RESERVED_FOR_TABLE_ALIAS_MYSQL.contains(kw))
@ -171,13 +171,13 @@ impl Dialect for MySqlDialect {
/// `LOCK TABLES`
/// <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
fn parse_lock_tables(parser: &mut Parser) -> Result<Statement, ParserError> {
fn parse_lock_tables(parser: &Parser) -> Result<Statement, ParserError> {
let tables = parser.parse_comma_separated(parse_lock_table)?;
Ok(Statement::LockTables { tables })
}
// tbl_name [[AS] alias] lock_type
fn parse_lock_table(parser: &mut Parser) -> Result<LockTable, ParserError> {
fn parse_lock_table(parser: &Parser) -> Result<LockTable, ParserError> {
let table = parser.parse_identifier()?;
let alias =
parser.parse_optional_alias(&[Keyword::READ, Keyword::WRITE, Keyword::LOW_PRIORITY])?;
@ -191,7 +191,7 @@ fn parse_lock_table(parser: &mut Parser) -> Result<LockTable, ParserError> {
}
// READ [LOCAL] | [LOW_PRIORITY] WRITE
fn parse_lock_tables_type(parser: &mut Parser) -> Result<LockTableType, ParserError> {
fn parse_lock_tables_type(parser: &Parser) -> Result<LockTableType, ParserError> {
if parser.parse_keyword(Keyword::READ) {
if parser.parse_keyword(Keyword::LOCAL) {
Ok(LockTableType::Read { local: true })
@ -211,6 +211,6 @@ fn parse_lock_tables_type(parser: &mut Parser) -> Result<LockTableType, ParserEr
/// UNLOCK TABLES
/// <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
fn parse_unlock_tables(_parser: &mut Parser) -> Result<Statement, ParserError> {
fn parse_unlock_tables(_parser: &Parser) -> Result<Statement, ParserError> {
Ok(Statement::UnlockTables)
}

View file

@ -211,7 +211,7 @@ impl Dialect for SnowflakeDialect {
true
}
fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
fn parse_statement(&self, parser: &Parser) -> Option<Result<Statement, ParserError>> {
if parser.parse_keyword(Keyword::BEGIN) {
return Some(parser.parse_begin_exception_end());
}
@ -318,7 +318,7 @@ impl Dialect for SnowflakeDialect {
fn parse_column_option(
&self,
parser: &mut Parser,
parser: &Parser,
) -> Result<Option<Result<Option<ColumnOption>, ParserError>>, ParserError> {
parser.maybe_parse(|parser| {
let with = parser.parse_keyword(Keyword::WITH);
@ -391,7 +391,7 @@ impl Dialect for SnowflakeDialect {
true
}
fn is_column_alias(&self, kw: &Keyword, parser: &mut Parser) -> bool {
fn is_column_alias(&self, kw: &Keyword, parser: &Parser) -> bool {
match kw {
// The following keywords can be considered an alias as long as
// they are not followed by other tokens that may change their meaning
@ -437,7 +437,7 @@ impl Dialect for SnowflakeDialect {
}
}
fn is_table_alias(&self, kw: &Keyword, parser: &mut Parser) -> bool {
fn is_table_alias(&self, kw: &Keyword, parser: &Parser) -> bool {
match kw {
// The following keywords can be considered an alias as long as
// they are not followed by other tokens that may change their meaning
@ -521,7 +521,7 @@ impl Dialect for SnowflakeDialect {
}
}
fn is_table_factor(&self, kw: &Keyword, parser: &mut Parser) -> bool {
fn is_table_factor(&self, kw: &Keyword, parser: &Parser) -> bool {
match kw {
Keyword::LIMIT if peek_for_limit_options(parser) => false,
// Table function
@ -591,7 +591,7 @@ fn peek_for_limit_options(parser: &Parser) -> bool {
}
}
fn parse_file_staging_command(kw: Keyword, parser: &mut Parser) -> Result<Statement, ParserError> {
fn parse_file_staging_command(kw: Keyword, parser: &Parser) -> Result<Statement, ParserError> {
let stage = parse_snowflake_stage_name(parser)?;
let pattern = if parser.parse_keyword(Keyword::PATTERN) {
parser.expect_token(&Token::Eq)?;
@ -613,7 +613,7 @@ fn parse_file_staging_command(kw: Keyword, parser: &mut Parser) -> Result<Statem
/// Parse snowflake alter dynamic table.
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-table>
fn parse_alter_dynamic_table(parser: &mut Parser) -> Result<Statement, ParserError> {
fn parse_alter_dynamic_table(parser: &Parser) -> Result<Statement, ParserError> {
// Use parse_object_name(true) to support IDENTIFIER() function
let table_name = parser.parse_object_name(true)?;
@ -651,7 +651,7 @@ fn parse_alter_dynamic_table(parser: &mut Parser) -> Result<Statement, ParserErr
/// Parse snowflake alter session.
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-session>
fn parse_alter_session(parser: &mut Parser, set: bool) -> Result<Statement, ParserError> {
fn parse_alter_session(parser: &Parser, set: bool) -> Result<Statement, ParserError> {
let session_options = parse_session_options(parser, set)?;
Ok(Statement::AlterSession {
set,
@ -674,7 +674,7 @@ pub fn parse_create_table(
transient: bool,
iceberg: bool,
dynamic: bool,
parser: &mut Parser,
parser: &Parser,
) -> Result<Statement, ParserError> {
let if_not_exists = parser.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
let table_name = parser.parse_object_name(false)?;
@ -912,7 +912,7 @@ pub fn parse_create_table(
pub fn parse_create_database(
or_replace: bool,
transient: bool,
parser: &mut Parser,
parser: &Parser,
) -> Result<Statement, ParserError> {
let if_not_exists = parser.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
let name = parser.parse_object_name(false)?;
@ -1017,7 +1017,7 @@ pub fn parse_create_database(
}
pub fn parse_storage_serialization_policy(
parser: &mut Parser,
parser: &Parser,
) -> Result<StorageSerializationPolicy, ParserError> {
let next_token = parser.next_token();
match &next_token.token {
@ -1033,7 +1033,7 @@ pub fn parse_storage_serialization_policy(
pub fn parse_create_stage(
or_replace: bool,
temporary: bool,
parser: &mut Parser,
parser: &Parser,
) -> Result<Statement, ParserError> {
//[ IF NOT EXISTS ]
let if_not_exists = parser.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
@ -1092,7 +1092,7 @@ pub fn parse_create_stage(
})
}
pub fn parse_stage_name_identifier(parser: &mut Parser) -> Result<Ident, ParserError> {
pub fn parse_stage_name_identifier(parser: &Parser) -> Result<Ident, ParserError> {
let mut ident = String::new();
while let Some(next_token) = parser.next_token_no_skip() {
match &next_token.token {
@ -1119,7 +1119,7 @@ pub fn parse_stage_name_identifier(parser: &mut Parser) -> Result<Ident, ParserE
Ok(Ident::new(ident))
}
pub fn parse_snowflake_stage_name(parser: &mut Parser) -> Result<ObjectName, ParserError> {
pub fn parse_snowflake_stage_name(parser: &Parser) -> Result<ObjectName, ParserError> {
match parser.next_token().token {
Token::AtSign => {
parser.prev_token();
@ -1141,7 +1141,7 @@ pub fn parse_snowflake_stage_name(parser: &mut Parser) -> Result<ObjectName, Par
/// Parses a `COPY INTO` statement. Snowflake has two variants, `COPY INTO <table>`
/// and `COPY INTO <location>` which have different syntax.
pub fn parse_copy_into(parser: &mut Parser) -> Result<Statement, ParserError> {
pub fn parse_copy_into(parser: &Parser) -> Result<Statement, ParserError> {
let kind = match parser.peek_token().token {
// Indicates an internal stage
Token::AtSign => CopyIntoSnowflakeKind::Location,
@ -1303,7 +1303,7 @@ pub fn parse_copy_into(parser: &mut Parser) -> Result<Statement, ParserError> {
}
fn parse_select_items_for_data_load(
parser: &mut Parser,
parser: &Parser,
) -> Result<Option<Vec<StageLoadSelectItemKind>>, ParserError> {
let mut select_items: Vec<StageLoadSelectItemKind> = vec![];
loop {
@ -1324,9 +1324,7 @@ fn parse_select_items_for_data_load(
Ok(Some(select_items))
}
fn parse_select_item_for_data_load(
parser: &mut Parser,
) -> Result<StageLoadSelectItem, ParserError> {
fn parse_select_item_for_data_load(parser: &Parser) -> Result<StageLoadSelectItem, ParserError> {
let mut alias: Option<Ident> = None;
let mut file_col_num: i32 = 0;
let mut element: Option<Ident> = None;
@ -1393,7 +1391,7 @@ fn parse_select_item_for_data_load(
})
}
fn parse_stage_params(parser: &mut Parser) -> Result<StageParamsObject, ParserError> {
fn parse_stage_params(parser: &Parser) -> Result<StageParamsObject, ParserError> {
let (mut url, mut storage_integration, mut endpoint) = (None, None, None);
let mut encryption: KeyValueOptions = KeyValueOptions {
options: vec![],
@ -1459,10 +1457,7 @@ fn parse_stage_params(parser: &mut Parser) -> Result<StageParamsObject, ParserEr
/// ABORT_DETACHED_QUERY = { TRUE | FALSE }
/// [ ACTIVE_PYTHON_PROFILER = { 'LINE' | 'MEMORY' } ]
/// [ BINARY_INPUT_FORMAT = '\<string\>' ]
fn parse_session_options(
parser: &mut Parser,
set: bool,
) -> Result<Vec<KeyValueOption>, ParserError> {
fn parse_session_options(parser: &Parser, set: bool) -> Result<Vec<KeyValueOption>, ParserError> {
let mut options: Vec<KeyValueOption> = Vec::new();
let empty = String::new;
loop {
@ -1505,7 +1500,7 @@ fn parse_session_options(
/// [ (seed , increment) | START num INCREMENT num ] [ ORDER | NOORDER ]
/// ```
/// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
fn parse_identity_property(parser: &mut Parser) -> Result<IdentityProperty, ParserError> {
fn parse_identity_property(parser: &Parser) -> Result<IdentityProperty, ParserError> {
let parameters = if parser.consume_token(&Token::LParen) {
let seed = parser.parse_number()?;
parser.expect_token(&Token::Comma)?;
@ -1541,7 +1536,7 @@ fn parse_identity_property(parser: &mut Parser) -> Result<IdentityProperty, Pars
/// ```
/// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
fn parse_column_policy_property(
parser: &mut Parser,
parser: &Parser,
with: bool,
) -> Result<ColumnPolicyProperty, ParserError> {
let policy_name = parser.parse_object_name(false)?;
@ -1567,7 +1562,7 @@ fn parse_column_policy_property(
/// ( <tag_name> = '<tag_value>' [ , <tag_name> = '<tag_value>' , ... ] )
/// ```
/// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
fn parse_column_tags(parser: &mut Parser, with: bool) -> Result<TagsColumnOption, ParserError> {
fn parse_column_tags(parser: &Parser, with: bool) -> Result<TagsColumnOption, ParserError> {
parser.expect_token(&Token::LParen)?;
let tags = parser.parse_comma_separated(Parser::parse_tag)?;
parser.expect_token(&Token::RParen)?;
@ -1577,7 +1572,7 @@ fn parse_column_tags(parser: &mut Parser, with: bool) -> Result<TagsColumnOption
/// Parse snowflake show objects.
/// <https://docs.snowflake.com/en/sql-reference/sql/show-objects>
fn parse_show_objects(terse: bool, parser: &mut Parser) -> Result<Statement, ParserError> {
fn parse_show_objects(terse: bool, parser: &Parser) -> Result<Statement, ParserError> {
let show_options = parser.parse_show_stmt_options()?;
Ok(Statement::ShowObjects(ShowObjects {
terse,

View file

@ -65,7 +65,7 @@ impl Dialect for SQLiteDialect {
self.is_identifier_start(ch) || ch.is_ascii_digit()
}
fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
fn parse_statement(&self, parser: &Parser) -> Option<Result<Statement, ParserError>> {
if parser.parse_keyword(Keyword::REPLACE) {
parser.prev_token();
Some(parser.parse_insert(parser.get_current_token().clone()))
@ -76,7 +76,7 @@ impl Dialect for SQLiteDialect {
fn parse_infix(
&self,
parser: &mut crate::parser::Parser,
parser: &crate::parser::Parser,
expr: &crate::ast::Expr,
_precedence: u8,
) -> Option<Result<crate::ast::Expr, ParserError>> {

View file

@ -30,7 +30,7 @@ use crate::{
};
impl Parser<'_> {
pub fn parse_alter_role(&mut self) -> Result<Statement, ParserError> {
pub fn parse_alter_role(&self) -> Result<Statement, ParserError> {
if dialect_of!(self is PostgreSqlDialect) {
return self.parse_pg_alter_role();
} else if dialect_of!(self is MsSqlDialect) {
@ -53,7 +53,7 @@ impl Parser<'_> {
/// ```
///
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterpolicy.html)
pub fn parse_alter_policy(&mut self) -> Result<Statement, ParserError> {
pub fn parse_alter_policy(&self) -> Result<Statement, ParserError> {
let name = self.parse_identifier()?;
self.expect_keyword_is(Keyword::ON)?;
let table_name = self.parse_object_name(false)?;
@ -110,7 +110,7 @@ impl Parser<'_> {
///
/// ALTER CONNECTOR connector_name SET OWNER [USER|ROLE] user_or_role;
/// ```
pub fn parse_alter_connector(&mut self) -> Result<Statement, ParserError> {
pub fn parse_alter_connector(&self) -> Result<Statement, ParserError> {
let name = self.parse_identifier()?;
self.expect_keyword_is(Keyword::SET)?;
@ -147,7 +147,7 @@ impl Parser<'_> {
/// ```sql
/// ALTER USER [ IF EXISTS ] [ <name> ] [ OPTIONS ]
/// ```
pub fn parse_alter_user(&mut self) -> Result<Statement, ParserError> {
pub fn parse_alter_user(&self) -> Result<Statement, ParserError> {
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
let name = self.parse_identifier()?;
let rename_to = if self.parse_keywords(&[Keyword::RENAME, Keyword::TO]) {
@ -314,7 +314,7 @@ impl Parser<'_> {
}))
}
fn parse_mfa_method(&mut self) -> Result<MfaMethodKind, ParserError> {
fn parse_mfa_method(&self) -> Result<MfaMethodKind, ParserError> {
if self.parse_keyword(Keyword::PASSKEY) {
Ok(MfaMethodKind::PassKey)
} else if self.parse_keyword(Keyword::TOTP) {
@ -326,7 +326,7 @@ impl Parser<'_> {
}
}
fn parse_mssql_alter_role(&mut self) -> Result<Statement, ParserError> {
fn parse_mssql_alter_role(&self) -> Result<Statement, ParserError> {
let role_name = self.parse_identifier()?;
let operation = if self.parse_keywords(&[Keyword::ADD, Keyword::MEMBER]) {
@ -352,7 +352,7 @@ impl Parser<'_> {
})
}
fn parse_pg_alter_role(&mut self) -> Result<Statement, ParserError> {
fn parse_pg_alter_role(&self) -> Result<Statement, ParserError> {
let role_name = self.parse_identifier()?;
// [ IN DATABASE _`database_name`_ ]
@ -436,7 +436,7 @@ impl Parser<'_> {
})
}
fn parse_pg_role_option(&mut self) -> Result<RoleOption, ParserError> {
fn parse_pg_role_option(&self) -> Result<RoleOption, ParserError> {
let option = match self.parse_one_of_keywords(&[
Keyword::BYPASSRLS,
Keyword::NOBYPASSRLS,

File diff suppressed because it is too large Load diff

View file

@ -311,8 +311,7 @@ fn parse_insert_default_values() {
fn parse_insert_select_returning() {
// Dialects that support `RETURNING` as a column identifier do
// not support this syntax.
let dialects =
all_dialects_where(|d| !d.is_column_alias(&Keyword::RETURNING, &mut Parser::new(d)));
let dialects = all_dialects_where(|d| !d.is_column_alias(&Keyword::RETURNING, &Parser::new(d)));
dialects.verified_stmt("INSERT INTO t SELECT 1 RETURNING 2");
let stmt = dialects.verified_stmt("INSERT INTO t SELECT x RETURNING x AS y");
@ -5655,7 +5654,7 @@ fn parse_named_window_functions() {
WINDOW w AS (PARTITION BY x), win AS (ORDER BY y)";
supported_dialects.verified_stmt(sql);
let select = all_dialects_except(|d| d.is_table_alias(&Keyword::WINDOW, &mut Parser::new(d)))
let select = all_dialects_except(|d| d.is_table_alias(&Keyword::WINDOW, &Parser::new(d)))
.verified_only_select(sql);
const EXPECTED_PROJ_QTY: usize = 2;
@ -5686,7 +5685,7 @@ fn parse_named_window_functions() {
#[test]
fn parse_window_clause() {
let dialects = all_dialects_except(|d| d.is_table_alias(&Keyword::WINDOW, &mut Parser::new(d)));
let dialects = all_dialects_except(|d| d.is_table_alias(&Keyword::WINDOW, &Parser::new(d)));
let sql = "SELECT * \
FROM mytable \
WINDOW \
@ -5705,7 +5704,7 @@ fn parse_window_clause() {
let dialects = all_dialects_except(|d| {
d.is::<BigQueryDialect>()
|| d.is::<GenericDialect>()
|| d.is_table_alias(&Keyword::WINDOW, &mut Parser::new(d))
|| d.is_table_alias(&Keyword::WINDOW, &Parser::new(d))
});
let res = dialects.parse_sql_statements(sql);
assert_eq!(
@ -5716,7 +5715,7 @@ fn parse_window_clause() {
#[test]
fn test_parse_named_window() {
let dialects = all_dialects_except(|d| d.is_table_alias(&Keyword::WINDOW, &mut Parser::new(d)));
let dialects = all_dialects_except(|d| d.is_table_alias(&Keyword::WINDOW, &Parser::new(d)));
let sql = "SELECT \
MIN(c12) OVER window1 AS min1, \
MAX(c12) OVER window2 AS max1 \
@ -5875,8 +5874,8 @@ fn test_parse_named_window() {
#[test]
fn parse_window_and_qualify_clause() {
let dialects = all_dialects_except(|d| {
d.is_table_alias(&Keyword::WINDOW, &mut Parser::new(d))
|| d.is_table_alias(&Keyword::QUALIFY, &mut Parser::new(d))
d.is_table_alias(&Keyword::WINDOW, &Parser::new(d))
|| d.is_table_alias(&Keyword::QUALIFY, &Parser::new(d))
});
let sql = "SELECT \
MIN(c12) OVER window1 AS min1 \
@ -7614,7 +7613,7 @@ fn parse_join_syntax_variants() {
"SELECT c1 FROM t1 FULL JOIN t2 USING(c1)",
);
let dialects = all_dialects_except(|d| d.is_table_alias(&Keyword::OUTER, &mut Parser::new(d)));
let dialects = all_dialects_except(|d| d.is_table_alias(&Keyword::OUTER, &Parser::new(d)));
let res = dialects.parse_sql_statements("SELECT * FROM a OUTER JOIN b ON 1");
assert_eq!(
ParserError::ParserError("Expected: APPLY, found: JOIN".to_string()),
@ -7829,7 +7828,7 @@ fn parse_union_except_intersect_minus() {
// Dialects that support `MINUS` as column identifier
// do not support `MINUS` as a set operator.
let dialects = all_dialects_where(|d| !d.is_column_alias(&Keyword::MINUS, &mut Parser::new(d)));
let dialects = all_dialects_where(|d| !d.is_column_alias(&Keyword::MINUS, &Parser::new(d)));
dialects.verified_stmt("SELECT 1 MINUS SELECT 2");
dialects.verified_stmt("SELECT 1 MINUS ALL SELECT 2");
dialects.verified_stmt("SELECT 1 MINUS DISTINCT SELECT 1");
@ -8592,8 +8591,7 @@ fn parse_invalid_subquery_without_parens() {
fn parse_offset() {
// Dialects that support `OFFSET` as column identifiers
// don't support this syntax.
let dialects =
all_dialects_where(|d| !d.is_column_alias(&Keyword::OFFSET, &mut Parser::new(d)));
let dialects = all_dialects_where(|d| !d.is_column_alias(&Keyword::OFFSET, &Parser::new(d)));
let expected_limit_clause = &Some(LimitClause::LimitOffset {
limit: None,
@ -12454,7 +12452,7 @@ fn test_buffer_reuse() {
Tokenizer::new(&d, q)
.tokenize_with_location_into_buf(&mut buf)
.unwrap();
let mut p = Parser::new(&d).with_tokens_with_locations(buf);
let p = Parser::new(&d).with_tokens_with_locations(buf);
p.parse_statements().unwrap();
let _ = p.into_tokens();
}
@ -15368,7 +15366,7 @@ fn parse_case_statement() {
#[test]
fn test_case_statement_span() {
let sql = "CASE 1 WHEN 2 THEN SELECT 1; SELECT 2; ELSE SELECT 3; END CASE";
let mut parser = Parser::new(&GenericDialect {}).try_with_sql(sql).unwrap();
let parser = Parser::new(&GenericDialect {}).try_with_sql(sql).unwrap();
assert_eq!(
parser.parse_statement().unwrap().span(),
Span::new(Location::new(1, 1), Location::new(1, sql.len() as u64 + 1))
@ -15449,7 +15447,7 @@ fn parse_if_statement() {
#[test]
fn test_if_statement_span() {
let sql = "IF 1=1 THEN SELECT 1; ELSEIF 1=2 THEN SELECT 2; ELSE SELECT 3; END IF";
let mut parser = Parser::new(&GenericDialect {}).try_with_sql(sql).unwrap();
let parser = Parser::new(&GenericDialect {}).try_with_sql(sql).unwrap();
assert_eq!(
parser.parse_statement().unwrap().span(),
Span::new(Location::new(1, 1), Location::new(1, sql.len() as u64 + 1))
@ -15463,7 +15461,7 @@ fn test_if_statement_multiline_span() {
let sql_line3 = "ELSE SELECT 3;";
let sql_line4 = "END IF";
let sql = [sql_line1, sql_line2, sql_line3, sql_line4].join("\n");
let mut parser = Parser::new(&GenericDialect {}).try_with_sql(&sql).unwrap();
let parser = Parser::new(&GenericDialect {}).try_with_sql(&sql).unwrap();
assert_eq!(
parser.parse_statement().unwrap().span(),
Span::new(
@ -15476,7 +15474,7 @@ fn test_if_statement_multiline_span() {
#[test]
fn test_conditional_statement_span() {
let sql = "IF 1=1 THEN SELECT 1; ELSEIF 1=2 THEN SELECT 2; ELSE SELECT 3; END IF";
let mut parser = Parser::new(&GenericDialect {}).try_with_sql(sql).unwrap();
let parser = Parser::new(&GenericDialect {}).try_with_sql(sql).unwrap();
match parser.parse_statement().unwrap() {
Statement::If(IfStatement {
if_block,
@ -16958,7 +16956,7 @@ fn test_select_exclude() {
let dialects = all_dialects_where(|d| {
d.supports_select_wildcard_exclude()
&& !d.supports_select_exclude()
&& d.is_column_alias(&Keyword::EXCLUDE, &mut Parser::new(d))
&& d.is_column_alias(&Keyword::EXCLUDE, &Parser::new(d))
});
assert_eq!(
dialects
@ -16973,7 +16971,7 @@ fn test_select_exclude() {
let dialects = all_dialects_where(|d| {
d.supports_select_wildcard_exclude()
&& !d.supports_select_exclude()
&& !d.is_column_alias(&Keyword::EXCLUDE, &mut Parser::new(d))
&& !d.is_column_alias(&Keyword::EXCLUDE, &Parser::new(d))
});
assert_eq!(
dialects

View file

@ -39,7 +39,7 @@ fn custom_prefix_parser() -> Result<(), ParserError> {
is_identifier_part(ch)
}
fn parse_prefix(&self, parser: &mut Parser) -> Option<Result<Expr, ParserError>> {
fn parse_prefix(&self, parser: &Parser) -> Option<Result<Expr, ParserError>> {
if parser.consume_token(&Token::Number("1".to_string(), false)) {
Some(Ok(Expr::Value(Value::Null.with_empty_span())))
} else {
@ -72,7 +72,7 @@ fn custom_infix_parser() -> Result<(), ParserError> {
fn parse_infix(
&self,
parser: &mut Parser,
parser: &Parser,
expr: &Expr,
_precedence: u8,
) -> Option<Result<Expr, ParserError>> {
@ -110,7 +110,7 @@ fn custom_statement_parser() -> Result<(), ParserError> {
is_identifier_part(ch)
}
fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
fn parse_statement(&self, parser: &Parser) -> Option<Result<Statement, ParserError>> {
if parser.parse_keyword(Keyword::SELECT) {
for _ in 0..3 {
let _ = parser.next_token();

View file

@ -2213,7 +2213,7 @@ fn parse_mssql_if_else() {
#[test]
fn test_mssql_if_else_span() {
let sql = "IF 1 = 1 SELECT '1' ELSE SELECT '2'";
let mut parser = Parser::new(&MsSqlDialect {}).try_with_sql(sql).unwrap();
let parser = Parser::new(&MsSqlDialect {}).try_with_sql(sql).unwrap();
assert_eq!(
parser.parse_statement().unwrap().span(),
Span::new(Location::new(1, 1), Location::new(1, sql.len() as u64 + 1))
@ -2226,7 +2226,7 @@ fn test_mssql_if_else_multiline_span() {
let sql_line2 = "SELECT '1'";
let sql_line3 = "ELSE SELECT '2'";
let sql = [sql_line1, sql_line2, sql_line3].join("\n");
let mut parser = Parser::new(&MsSqlDialect {}).try_with_sql(&sql).unwrap();
let parser = Parser::new(&MsSqlDialect {}).try_with_sql(&sql).unwrap();
assert_eq!(
parser.parse_statement().unwrap().span(),
Span::new(