mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-12-23 11:12:51 +00:00
MSSQL: Parse IF/ELSE without semicolon delimiters (#2128)
Some checks failed
license / Release Audit Tool (RAT) (push) Has been cancelled
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
Some checks failed
license / Release Audit Tool (RAT) (push) Has been cancelled
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
This commit is contained in:
parent
0b1e0c35d9
commit
1b842d3b6a
3 changed files with 62 additions and 12 deletions
|
|
@ -21,14 +21,12 @@ use crate::ast::{
|
|||
GranteesType, IfStatement, Statement,
|
||||
};
|
||||
use crate::dialect::Dialect;
|
||||
use crate::keywords::{self, Keyword};
|
||||
use crate::keywords::Keyword;
|
||||
use crate::parser::{Parser, ParserError};
|
||||
use crate::tokenizer::Token;
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::{vec, vec::Vec};
|
||||
|
||||
const RESERVED_FOR_COLUMN_ALIAS: &[Keyword] = &[Keyword::IF, Keyword::ELSE];
|
||||
|
||||
/// A [`Dialect`] for [Microsoft SQL Server](https://www.microsoft.com/en-us/sql-server/)
|
||||
#[derive(Debug)]
|
||||
pub struct MsSqlDialect {}
|
||||
|
|
@ -128,8 +126,22 @@ impl Dialect for MsSqlDialect {
|
|||
&[GranteesType::Public]
|
||||
}
|
||||
|
||||
fn is_column_alias(&self, kw: &Keyword, _parser: &mut Parser) -> bool {
|
||||
!keywords::RESERVED_FOR_COLUMN_ALIAS.contains(kw) && !RESERVED_FOR_COLUMN_ALIAS.contains(kw)
|
||||
fn is_select_item_alias(&self, explicit: bool, kw: &Keyword, parser: &mut Parser) -> bool {
|
||||
match kw {
|
||||
// List of keywords that cannot be used as select item aliases in MSSQL
|
||||
// regardless of whether the alias is explicit or implicit
|
||||
Keyword::IF | Keyword::ELSE => false,
|
||||
_ => explicit || self.is_column_alias(kw, parser),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_table_factor_alias(&self, explicit: bool, kw: &Keyword, parser: &mut Parser) -> bool {
|
||||
match kw {
|
||||
// List of keywords that cannot be used as table aliases in MSSQL
|
||||
// regardless of whether the alias is explicit or implicit
|
||||
Keyword::IF | Keyword::ELSE => false,
|
||||
_ => explicit || self.is_table_alias(kw, parser),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
|
||||
|
|
|
|||
|
|
@ -11503,16 +11503,17 @@ impl<'a> Parser<'a> {
|
|||
|
||||
let next_token = self.next_token();
|
||||
match next_token.token {
|
||||
// By default, if a word is located after the `AS` keyword we consider it an alias
|
||||
// as long as it's not reserved.
|
||||
// Accepts a keyword as an alias if the AS keyword explicitly indicate an alias or if the
|
||||
// caller provided a list of reserved keywords and the keyword is not on that list.
|
||||
Token::Word(w)
|
||||
if after_as || reserved_kwds.is_some_and(|x| !x.contains(&w.keyword)) =>
|
||||
if reserved_kwds.is_some()
|
||||
&& (after_as || reserved_kwds.is_some_and(|x| !x.contains(&w.keyword))) =>
|
||||
{
|
||||
Ok(Some(w.into_ident(next_token.span)))
|
||||
}
|
||||
// This pattern allows for customizing the acceptance of words as aliases based on the caller's
|
||||
// context, such as to what SQL element this word is a potential alias of (select item alias, table name
|
||||
// alias, etc.) or dialect-specific logic that goes beyond a simple list of reserved keywords.
|
||||
// Accepts a keyword as alias based on the caller's context, such as to what SQL element
|
||||
// this word is a potential alias of using the validator call-back. This allows for
|
||||
// dialect-specific logic.
|
||||
Token::Word(w) if validator(after_as, &w.keyword, self) => {
|
||||
Ok(Some(w.into_ident(next_token.span)))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue