mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-26 23:49:10 +00:00
Snowflake: Improve support for reserved keywords for table factor (#1942)
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
This commit is contained in:
parent
85fa881379
commit
3d2db8c69b
4 changed files with 103 additions and 12 deletions
|
@ -963,12 +963,6 @@ pub trait Dialect: Debug + Any {
|
|||
keywords::RESERVED_FOR_IDENTIFIER.contains(&kw)
|
||||
}
|
||||
|
||||
/// Returns reserved keywords when looking to parse a `TableFactor`.
|
||||
/// See [Self::supports_from_trailing_commas]
|
||||
fn get_reserved_keywords_for_table_factor(&self) -> &[Keyword] {
|
||||
keywords::RESERVED_FOR_TABLE_FACTOR
|
||||
}
|
||||
|
||||
/// Returns reserved keywords that may prefix a select item expression
|
||||
/// e.g. `SELECT CONNECT_BY_ROOT name FROM Tbl2` (Snowflake)
|
||||
fn get_reserved_keywords_for_select_item_operator(&self) -> &[Keyword] {
|
||||
|
@ -1027,7 +1021,13 @@ 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.
|
||||
/// 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 {
|
||||
!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 {
|
||||
!keywords::RESERVED_FOR_TABLE_ALIAS.contains(kw)
|
||||
|
|
|
@ -47,6 +47,82 @@ use super::keywords::RESERVED_FOR_IDENTIFIER;
|
|||
use sqlparser::ast::StorageSerializationPolicy;
|
||||
|
||||
const RESERVED_KEYWORDS_FOR_SELECT_ITEM_OPERATOR: [Keyword; 1] = [Keyword::CONNECT_BY_ROOT];
|
||||
|
||||
// See: <https://docs.snowflake.com/en/sql-reference/reserved-keywords>
|
||||
const RESERVED_KEYWORDS_FOR_TABLE_FACTOR: &[Keyword] = &[
|
||||
Keyword::ALL,
|
||||
Keyword::ALTER,
|
||||
Keyword::AND,
|
||||
Keyword::ANY,
|
||||
Keyword::AS,
|
||||
Keyword::BETWEEN,
|
||||
Keyword::BY,
|
||||
Keyword::CHECK,
|
||||
Keyword::COLUMN,
|
||||
Keyword::CONNECT,
|
||||
Keyword::CREATE,
|
||||
Keyword::CROSS,
|
||||
Keyword::CURRENT,
|
||||
Keyword::DELETE,
|
||||
Keyword::DISTINCT,
|
||||
Keyword::DROP,
|
||||
Keyword::ELSE,
|
||||
Keyword::EXISTS,
|
||||
Keyword::FOLLOWING,
|
||||
Keyword::FOR,
|
||||
Keyword::FROM,
|
||||
Keyword::FULL,
|
||||
Keyword::GRANT,
|
||||
Keyword::GROUP,
|
||||
Keyword::HAVING,
|
||||
Keyword::ILIKE,
|
||||
Keyword::IN,
|
||||
Keyword::INCREMENT,
|
||||
Keyword::INNER,
|
||||
Keyword::INSERT,
|
||||
Keyword::INTERSECT,
|
||||
Keyword::INTO,
|
||||
Keyword::IS,
|
||||
Keyword::JOIN,
|
||||
Keyword::LEFT,
|
||||
Keyword::LIKE,
|
||||
Keyword::MINUS,
|
||||
Keyword::NATURAL,
|
||||
Keyword::NOT,
|
||||
Keyword::NULL,
|
||||
Keyword::OF,
|
||||
Keyword::ON,
|
||||
Keyword::OR,
|
||||
Keyword::ORDER,
|
||||
Keyword::QUALIFY,
|
||||
Keyword::REGEXP,
|
||||
Keyword::REVOKE,
|
||||
Keyword::RIGHT,
|
||||
Keyword::RLIKE,
|
||||
Keyword::ROW,
|
||||
Keyword::ROWS,
|
||||
Keyword::SAMPLE,
|
||||
Keyword::SELECT,
|
||||
Keyword::SET,
|
||||
Keyword::SOME,
|
||||
Keyword::START,
|
||||
Keyword::TABLE,
|
||||
Keyword::TABLESAMPLE,
|
||||
Keyword::THEN,
|
||||
Keyword::TO,
|
||||
Keyword::TRIGGER,
|
||||
Keyword::UNION,
|
||||
Keyword::UNIQUE,
|
||||
Keyword::UPDATE,
|
||||
Keyword::USING,
|
||||
Keyword::VALUES,
|
||||
Keyword::WHEN,
|
||||
Keyword::WHENEVER,
|
||||
Keyword::WHERE,
|
||||
Keyword::WINDOW,
|
||||
Keyword::WITH,
|
||||
];
|
||||
|
||||
/// A [`Dialect`] for [Snowflake](https://www.snowflake.com/)
|
||||
#[derive(Debug, Default)]
|
||||
pub struct SnowflakeDialect;
|
||||
|
@ -433,6 +509,13 @@ impl Dialect for SnowflakeDialect {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_table_factor(&self, kw: &Keyword, parser: &mut Parser) -> bool {
|
||||
match kw {
|
||||
Keyword::LIMIT if peek_for_limit_options(parser) => false,
|
||||
_ => !RESERVED_KEYWORDS_FOR_TABLE_FACTOR.contains(kw),
|
||||
}
|
||||
}
|
||||
|
||||
/// See: <https://docs.snowflake.com/en/sql-reference/constructs/at-before>
|
||||
fn supports_timestamp_versioning(&self) -> bool {
|
||||
true
|
||||
|
|
|
@ -4449,11 +4449,7 @@ impl<'a> Parser<'a> {
|
|||
self.parse_comma_separated_with_trailing_commas(
|
||||
Parser::parse_table_and_joins,
|
||||
trailing_commas,
|
||||
|kw, _parser| {
|
||||
self.dialect
|
||||
.get_reserved_keywords_for_table_factor()
|
||||
.contains(kw)
|
||||
},
|
||||
|kw, parser| !self.dialect.is_table_factor(kw, parser),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -3606,6 +3606,18 @@ fn test_sql_keywords_as_table_aliases() {
|
|||
snowflake().verified_stmt("SELECT * FROM tbl LIMIT $$$$");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sql_keywords_as_table_factor() {
|
||||
// LIMIT is a table factor, Snowflake does not reserve it
|
||||
snowflake().one_statement_parses_to("SELECT * FROM tbl, LIMIT", "SELECT * FROM tbl, LIMIT");
|
||||
// LIMIT is not a table factor
|
||||
snowflake().one_statement_parses_to("SELECT * FROM tbl, LIMIT 1", "SELECT * FROM tbl LIMIT 1");
|
||||
// ORDER is reserved
|
||||
assert!(snowflake()
|
||||
.parse_sql_statements("SELECT * FROM tbl, order")
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timetravel_at_before() {
|
||||
snowflake().verified_only_select("SELECT * FROM tbl AT(TIMESTAMP => '2024-12-15 00:00:00')");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue