Skip to content

Commit abec6f9

Browse files
andygroveclaude
andauthored
Refactor: replace some dialect_of! checks with Dialect trait methods (apache#2171)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 845e213 commit abec6f9

File tree

5 files changed

+138
-7
lines changed

5 files changed

+138
-7
lines changed

src/dialect/databricks.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,9 @@ impl Dialect for DatabricksDialect {
7979
fn supports_group_by_with_modifier(&self) -> bool {
8080
true
8181
}
82+
83+
/// See <https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select-values.html>
84+
fn supports_values_as_table_factor(&self) -> bool {
85+
true
86+
}
8287
}

src/dialect/generic.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,22 @@ impl Dialect for GenericDialect {
104104
true
105105
}
106106

107+
fn supports_extract_comma_syntax(&self) -> bool {
108+
true
109+
}
110+
111+
fn supports_create_view_comment_syntax(&self) -> bool {
112+
true
113+
}
114+
115+
fn supports_parens_around_table_factor(&self) -> bool {
116+
true
117+
}
118+
119+
fn supports_values_as_table_factor(&self) -> bool {
120+
true
121+
}
122+
107123
fn supports_create_index_with_clause(&self) -> bool {
108124
true
109125
}

src/dialect/mod.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,87 @@ pub trait Dialect: Debug + Any {
856856
false
857857
}
858858

859+
/// Returns true if this dialect supports the `EXTRACT` function
860+
/// with a comma separator instead of `FROM`.
861+
///
862+
/// Example:
863+
/// ```sql
864+
/// SELECT EXTRACT(YEAR, date_column) FROM table;
865+
/// ```
866+
///
867+
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/functions/extract)
868+
fn supports_extract_comma_syntax(&self) -> bool {
869+
false
870+
}
871+
872+
/// Returns true if this dialect supports a subquery passed to a function
873+
/// as the only argument without enclosing parentheses.
874+
///
875+
/// Example:
876+
/// ```sql
877+
/// SELECT FLATTEN(SELECT * FROM tbl);
878+
/// ```
879+
///
880+
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/functions/flatten)
881+
fn supports_subquery_as_function_arg(&self) -> bool {
882+
false
883+
}
884+
885+
/// Returns true if this dialect supports the `COMMENT` clause in
886+
/// `CREATE VIEW` statements using the `COMMENT = 'comment'` syntax.
887+
///
888+
/// Example:
889+
/// ```sql
890+
/// CREATE VIEW v COMMENT = 'my comment' AS SELECT 1;
891+
/// ```
892+
///
893+
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-view#optional-parameters)
894+
fn supports_create_view_comment_syntax(&self) -> bool {
895+
false
896+
}
897+
898+
/// Returns true if this dialect supports the `ARRAY` type without
899+
/// specifying an element type.
900+
///
901+
/// Example:
902+
/// ```sql
903+
/// CREATE TABLE t (a ARRAY);
904+
/// ```
905+
///
906+
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/data-types-semistructured#array)
907+
fn supports_array_typedef_without_element_type(&self) -> bool {
908+
false
909+
}
910+
911+
/// Returns true if this dialect supports extra parentheses around
912+
/// lone table names or derived tables in the `FROM` clause.
913+
///
914+
/// Example:
915+
/// ```sql
916+
/// SELECT * FROM (mytable);
917+
/// SELECT * FROM ((SELECT 1));
918+
/// SELECT * FROM (mytable) AS alias;
919+
/// ```
920+
///
921+
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/constructs/from)
922+
fn supports_parens_around_table_factor(&self) -> bool {
923+
false
924+
}
925+
926+
/// Returns true if this dialect supports `VALUES` as a table factor
927+
/// without requiring parentheses around the entire clause.
928+
///
929+
/// Example:
930+
/// ```sql
931+
/// SELECT * FROM VALUES (1, 'a'), (2, 'b') AS t (col1, col2);
932+
/// ```
933+
///
934+
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/constructs/values)
935+
/// [Databricks](https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select-values.html)
936+
fn supports_values_as_table_factor(&self) -> bool {
937+
false
938+
}
939+
859940
/// Returns true if this dialect allows dollar placeholders
860941
/// e.g. `SELECT $var` (SQLite)
861942
fn supports_dollar_placeholder(&self) -> bool {

src/dialect/snowflake.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,36 @@ impl Dialect for SnowflakeDialect {
211211
true
212212
}
213213

214+
/// See [doc](https://docs.snowflake.com/en/sql-reference/functions/extract)
215+
fn supports_extract_comma_syntax(&self) -> bool {
216+
true
217+
}
218+
219+
/// See [doc](https://docs.snowflake.com/en/sql-reference/functions/flatten)
220+
fn supports_subquery_as_function_arg(&self) -> bool {
221+
true
222+
}
223+
224+
/// See [doc](https://docs.snowflake.com/en/sql-reference/sql/create-view#optional-parameters)
225+
fn supports_create_view_comment_syntax(&self) -> bool {
226+
true
227+
}
228+
229+
/// See [doc](https://docs.snowflake.com/en/sql-reference/data-types-semistructured#array)
230+
fn supports_array_typedef_without_element_type(&self) -> bool {
231+
true
232+
}
233+
234+
/// See [doc](https://docs.snowflake.com/en/sql-reference/constructs/from)
235+
fn supports_parens_around_table_factor(&self) -> bool {
236+
true
237+
}
238+
239+
/// See [doc](https://docs.snowflake.com/en/sql-reference/constructs/values)
240+
fn supports_values_as_table_factor(&self) -> bool {
241+
true
242+
}
243+
214244
fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
215245
if parser.parse_keyword(Keyword::BEGIN) {
216246
return Some(parser.parse_begin_exception_end());

src/parser/mod.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,7 +2293,7 @@ impl<'a> Parser<'a> {
22932293

22942294
// Snowflake permits a subquery to be passed as an argument without
22952295
// an enclosing set of parens if it's the only argument.
2296-
if dialect_of!(self is SnowflakeDialect) && self.peek_sub_query() {
2296+
if self.dialect.supports_subquery_as_function_arg() && self.peek_sub_query() {
22972297
let subquery = self.parse_query()?;
22982298
self.expect_token(&Token::RParen)?;
22992299
return Ok(Function {
@@ -2683,8 +2683,7 @@ impl<'a> Parser<'a> {
26832683

26842684
let syntax = if self.parse_keyword(Keyword::FROM) {
26852685
ExtractSyntax::From
2686-
} else if self.consume_token(&Token::Comma)
2687-
&& dialect_of!(self is SnowflakeDialect | GenericDialect)
2686+
} else if self.dialect.supports_extract_comma_syntax() && self.consume_token(&Token::Comma)
26882687
{
26892688
ExtractSyntax::Comma
26902689
} else {
@@ -6228,7 +6227,7 @@ impl<'a> Parser<'a> {
62286227
None
62296228
};
62306229

6231-
let comment = if dialect_of!(self is SnowflakeDialect | GenericDialect)
6230+
let comment = if self.dialect.supports_create_view_comment_syntax()
62326231
&& self.parse_keyword(Keyword::COMMENT)
62336232
{
62346233
self.expect_token(&Token::Eq)?;
@@ -11790,7 +11789,7 @@ impl<'a> Parser<'a> {
1179011789
Keyword::ENUM16 => Ok(DataType::Enum(self.parse_enum_values()?, Some(16))),
1179111790
Keyword::SET => Ok(DataType::Set(self.parse_string_values()?)),
1179211791
Keyword::ARRAY => {
11793-
if dialect_of!(self is SnowflakeDialect) {
11792+
if self.dialect.supports_array_typedef_without_element_type() {
1179411793
Ok(DataType::Array(ArrayElemTypeDef::None))
1179511794
} else if dialect_of!(self is ClickHouseDialect) {
1179611795
Ok(self.parse_sub_type(|internal_type| {
@@ -14989,7 +14988,7 @@ impl<'a> Parser<'a> {
1498914988
table_with_joins: Box::new(table_and_joins),
1499014989
alias,
1499114990
})
14992-
} else if dialect_of!(self is SnowflakeDialect | GenericDialect) {
14991+
} else if self.dialect.supports_parens_around_table_factor() {
1499314992
// Dialect-specific behavior: Snowflake diverges from the
1499414993
// standard and from most of the other implementations by
1499514994
// allowing extra parentheses not only around a join (B), but
@@ -15035,7 +15034,7 @@ impl<'a> Parser<'a> {
1503515034
// appearing alone in parentheses (e.g. `FROM (mytable)`)
1503615035
self.expected("joined table", self.peek_token())
1503715036
}
15038-
} else if dialect_of!(self is SnowflakeDialect | DatabricksDialect | GenericDialect)
15037+
} else if self.dialect.supports_values_as_table_factor()
1503915038
&& matches!(
1504015039
self.peek_tokens(),
1504115040
[

0 commit comments

Comments
 (0)