mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-01 11:47:20 +00:00
Snowflake Reserved SQL Keywords as Implicit Table Alias (#1934)
This commit is contained in:
parent
fd4934ec74
commit
15f35e1476
4 changed files with 163 additions and 12 deletions
|
@ -992,11 +992,17 @@ pub trait Dialect: Debug + Any {
|
|||
explicit || self.is_column_alias(kw, parser)
|
||||
}
|
||||
|
||||
/// Returns true if the specified keyword should be parsed as a table identifier.
|
||||
/// See [keywords::RESERVED_FOR_TABLE_ALIAS]
|
||||
fn is_table_alias(&self, kw: &Keyword, _parser: &mut 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 {
|
||||
explicit || !keywords::RESERVED_FOR_TABLE_ALIAS.contains(kw)
|
||||
fn is_table_factor_alias(&self, explicit: bool, kw: &Keyword, parser: &mut Parser) -> bool {
|
||||
explicit || self.is_table_alias(kw, parser)
|
||||
}
|
||||
|
||||
/// Returns true if this dialect supports querying historical table data
|
||||
|
|
|
@ -318,9 +318,11 @@ impl Dialect for SnowflakeDialect {
|
|||
}
|
||||
|
||||
// `FETCH` can be considered an alias as long as it's not followed by `FIRST`` or `NEXT`
|
||||
// which would give it a different meanings, for example: `SELECT 1 FETCH FIRST 10 ROWS` - not an alias
|
||||
Keyword::FETCH
|
||||
if parser.peek_keyword(Keyword::FIRST) || parser.peek_keyword(Keyword::NEXT) =>
|
||||
// which would give it a different meanings, for example:
|
||||
// `SELECT 1 FETCH FIRST 10 ROWS` - not an alias
|
||||
// `SELECT 1 FETCH 10` - not an alias
|
||||
Keyword::FETCH if parser.peek_one_of_keywords(&[Keyword::FIRST, Keyword::NEXT]).is_some()
|
||||
|| matches!(parser.peek_token().token, Token::Number(_, _)) =>
|
||||
{
|
||||
false
|
||||
}
|
||||
|
@ -345,6 +347,86 @@ impl Dialect for SnowflakeDialect {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_table_alias(&self, kw: &Keyword, parser: &mut 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
|
||||
Keyword::LIMIT
|
||||
| Keyword::RETURNING
|
||||
| Keyword::INNER
|
||||
| Keyword::USING
|
||||
| Keyword::PIVOT
|
||||
| Keyword::UNPIVOT
|
||||
| Keyword::EXCEPT
|
||||
| Keyword::MATCH_RECOGNIZE
|
||||
| Keyword::OFFSET
|
||||
if !matches!(parser.peek_token_ref().token, Token::SemiColon | Token::EOF) =>
|
||||
{
|
||||
false
|
||||
}
|
||||
|
||||
// `FETCH` can be considered an alias as long as it's not followed by `FIRST`` or `NEXT`
|
||||
// which would give it a different meanings, for example:
|
||||
// `SELECT * FROM tbl FETCH FIRST 10 ROWS` - not an alias
|
||||
// `SELECT * FROM tbl FETCH 10` - not an alias
|
||||
Keyword::FETCH
|
||||
if parser
|
||||
.peek_one_of_keywords(&[Keyword::FIRST, Keyword::NEXT])
|
||||
.is_some()
|
||||
|| matches!(parser.peek_token().token, Token::Number(_, _)) =>
|
||||
{
|
||||
false
|
||||
}
|
||||
|
||||
// All sorts of join-related keywords can be considered aliases unless additional
|
||||
// keywords change their meaning.
|
||||
Keyword::RIGHT | Keyword::LEFT | Keyword::SEMI | Keyword::ANTI
|
||||
if parser
|
||||
.peek_one_of_keywords(&[Keyword::JOIN, Keyword::OUTER])
|
||||
.is_some() =>
|
||||
{
|
||||
false
|
||||
}
|
||||
Keyword::GLOBAL if parser.peek_keyword(Keyword::FULL) => false,
|
||||
|
||||
// Reserved keywords by the Snowflake dialect, which seem to be less strictive
|
||||
// than what is listed in `keywords::RESERVED_FOR_TABLE_ALIAS`. The following
|
||||
// keywords were tested with the this statement: `SELECT <KW>.* FROM tbl <KW>`.
|
||||
Keyword::WITH
|
||||
| Keyword::ORDER
|
||||
| Keyword::SELECT
|
||||
| Keyword::WHERE
|
||||
| Keyword::GROUP
|
||||
| Keyword::HAVING
|
||||
| Keyword::LATERAL
|
||||
| Keyword::UNION
|
||||
| Keyword::INTERSECT
|
||||
| Keyword::MINUS
|
||||
| Keyword::ON
|
||||
| Keyword::JOIN
|
||||
| Keyword::INNER
|
||||
| Keyword::CROSS
|
||||
| Keyword::FULL
|
||||
| Keyword::LEFT
|
||||
| Keyword::RIGHT
|
||||
| Keyword::NATURAL
|
||||
| Keyword::USING
|
||||
| Keyword::ASOF
|
||||
| Keyword::MATCH_CONDITION
|
||||
| Keyword::SET
|
||||
| Keyword::QUALIFY
|
||||
| Keyword::FOR
|
||||
| Keyword::START
|
||||
| Keyword::CONNECT
|
||||
| Keyword::SAMPLE
|
||||
| Keyword::TABLESAMPLE
|
||||
| Keyword::FROM => false,
|
||||
|
||||
// Any other word is considered an alias
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
/// See: <https://docs.snowflake.com/en/sql-reference/constructs/at-before>
|
||||
fn supports_timestamp_versioning(&self) -> bool {
|
||||
true
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue