Skip to content

SQL Server: Increase support for multi statement object definitions #1800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
aharpervc opened this issue Apr 7, 2025 · 0 comments
Open

Comments

@aharpervc
Copy link
Contributor

It would be extremely useful if this library was able to properly parse multiple statements, particularly in a object definition body, without requiring semi-colons which are optional for SQL Server.


The following otherwise valid SQL fails parsing (MSSQL dialect):

create or alter procedure test()
as
begin
    declare @x bit = 1

    if @x = 1
    begin
        select 1
    end
end

The error is at the if @x = 1 line:

end of statement, found: if

The problem appears to be related to parsing multiple statements in the object definition body. The parsing concludes successfully if the code is changed to declare @x bit = 1; with a semi-colon.

There's also the similar case of two top level statements:

declare @x bit = 1

if @x = 1
begin
    select 1
end

The API I was using was parse_sql:

static DIALECT: sqlparser::dialect::MsSqlDialect = sqlparser::dialect::MsSqlDialect {};
let sql_text = ...

let mut statements = Parser::parse_sql(&DIALECT, sql_text.as_str())?; // error: end of statement, found: if

There's a workaround for the multiple top level statements scenario, but that won't work for the stored procedure example:

fn parse_all_statements(sql_text: &str) -> Result<Vec<Statement>, Box<dyn std::error::Error>> {
    let mut parser = Parser::new(&DIALECT)
        .try_with_sql(&sql_text)?;

    let mut statements = Vec::new();

    loop {
        if let Token::EOF = parser.peek_token_ref().token {
            break;
        }

        statements.push(parser.parse_statement()?);

        while let Token::SemiColon = parser.peek_token_ref().token {
            parser.advance_token();
        }
    }

    return Ok(statements);
}

follow up from: #1791 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant