Skip to content

Commit 9ea9cb1

Browse files
committed
support snowflake double dot notation for object name
1 parent 0fb2ef3 commit 9ea9cb1

File tree

4 files changed

+54
-0
lines changed

4 files changed

+54
-0
lines changed

src/dialect/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,16 @@ pub trait Dialect: Debug + Any {
365365
self.supports_trailing_commas()
366366
}
367367

368+
/// Returns true if the dialect supports double dot notation for object names
369+
///
370+
/// Example
371+
/// ```sql
372+
/// SELECT * FROM db_name..table_name
373+
/// ```
374+
fn supports_object_name_double_dot_notation(&self) -> bool {
375+
false
376+
}
377+
368378
/// Dialect-specific infix parser override
369379
///
370380
/// This method is called to parse the next infix expression.

src/dialect/snowflake.rs

+8
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ impl Dialect for SnowflakeDialect {
5252
true
5353
}
5454

55+
// Snowflake supports double-dot notation when the schema name is not specified
56+
// In this case the default PUBLIC schema is used
57+
//
58+
// see https://docs.snowflake.com/en/sql-reference/name-resolution#resolution-when-schema-omitted-double-dot-notation
59+
fn supports_object_name_double_dot_notation(&self) -> bool {
60+
true
61+
}
62+
5563
fn is_identifier_part(&self, ch: char) -> bool {
5664
ch.is_ascii_lowercase()
5765
|| ch.is_ascii_uppercase()

src/parser/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -8382,6 +8382,13 @@ impl<'a> Parser<'a> {
83828382
pub fn parse_object_name(&mut self, in_table_clause: bool) -> Result<ObjectName, ParserError> {
83838383
let mut idents = vec![];
83848384
loop {
8385+
if self.dialect.supports_object_name_double_dot_notation()
8386+
&& !idents.is_empty()
8387+
&& self.peek_token() == Token::Period
8388+
{
8389+
self.next_token();
8390+
idents.push(Ident::new(""));
8391+
}
83858392
idents.push(self.parse_identifier(in_table_clause)?);
83868393
if !self.consume_token(&Token::Period) {
83878394
break;

tests/sqlparser_snowflake.rs

+29
Original file line numberDiff line numberDiff line change
@@ -2864,3 +2864,32 @@ fn test_projection_with_nested_trailing_commas() {
28642864
let sql = "SELECT a, b, FROM c, (SELECT d, e, FROM f, LATERAL FLATTEN(input => events))";
28652865
let _ = snowflake().parse_sql_statements(sql).unwrap();
28662866
}
2867+
2868+
#[test]
2869+
fn test_sf_double_dot_notation() {
2870+
snowflake().verified_stmt("SELECT * FROM db_name..table_name");
2871+
snowflake().verified_stmt("SELECT * FROM x, y..z JOIN a..b as as b ON x.id = b.id");
2872+
}
2873+
2874+
#[test]
2875+
fn test_sf_double_dot_notation_wrong_position() {}
2876+
2877+
#[test]
2878+
fn test_parse_double_dot_notation_wrong_position() {
2879+
assert_eq!(
2880+
snowflake()
2881+
.parse_sql_statements("SELECT * FROM X.Y..")
2882+
.unwrap_err()
2883+
.to_string(),
2884+
"sql parser error: Expected: identifier, found: ."
2885+
);
2886+
2887+
assert_eq!(
2888+
// Ensure we don't parse leading token
2889+
snowflake()
2890+
.parse_sql_statements("SELECT * FROM .X.Y")
2891+
.unwrap_err()
2892+
.to_string(),
2893+
"sql parser error: Expected: identifier, found: ."
2894+
);
2895+
}

0 commit comments

Comments
 (0)