Skip to content

Commit f4f112d

Browse files
authored
Support snowflake double dot notation for object name (#1540)
1 parent 96f7c02 commit f4f112d

File tree

4 files changed

+57
-0
lines changed

4 files changed

+57
-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
@@ -54,6 +54,14 @@ impl Dialect for SnowflakeDialect {
5454
true
5555
}
5656

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

src/parser/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -8457,6 +8457,13 @@ impl<'a> Parser<'a> {
84578457
pub fn parse_object_name(&mut self, in_table_clause: bool) -> Result<ObjectName, ParserError> {
84588458
let mut idents = vec![];
84598459
loop {
8460+
if self.dialect.supports_object_name_double_dot_notation()
8461+
&& idents.len() == 1
8462+
&& self.consume_token(&Token::Period)
8463+
{
8464+
// Empty string here means default schema
8465+
idents.push(Ident::new(""));
8466+
}
84608467
idents.push(self.parse_identifier(in_table_clause)?);
84618468
if !self.consume_token(&Token::Period) {
84628469
break;

tests/sqlparser_snowflake.rs

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

0 commit comments

Comments
 (0)