From 4ede0f0ed6d5a26ab0d984a3af020e017170a8ed Mon Sep 17 00:00:00 2001 From: Yoav Cohen Date: Thu, 10 Jul 2025 04:45:31 +0200 Subject: [PATCH 1/2] Add support for + char in Snowflake stage names --- src/dialect/snowflake.rs | 1 + tests/sqlparser_snowflake.rs | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/dialect/snowflake.rs b/src/dialect/snowflake.rs index 212cf217d..c7440db73 100644 --- a/src/dialect/snowflake.rs +++ b/src/dialect/snowflake.rs @@ -718,6 +718,7 @@ pub fn parse_stage_name_identifier(parser: &mut Parser) -> Result ident.push('~'), Token::Mod => ident.push('%'), Token::Div => ident.push('/'), + Token::Plus => ident.push('+'), Token::Word(w) => ident.push_str(&w.to_string()), _ => return parser.expected("stage name identifier", parser.peek_token()), } diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index e7393d3f8..c81d8950b 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -2581,6 +2581,26 @@ fn test_snowflake_copy_into() { } _ => unreachable!(), } + + // Test for non-ident characters in stage names + let sql = "COPY INTO a.b FROM @namespace.stage_name/x@x~x%x+"; + assert_eq!(snowflake().verified_stmt(sql).to_string(), sql); + match snowflake().verified_stmt(sql) { + Statement::CopyIntoSnowflake { into, from_obj, .. } => { + assert_eq!( + into, + ObjectName::from(vec![Ident::new("a"), Ident::new("b")]) + ); + assert_eq!( + from_obj, + Some(ObjectName::from(vec![ + Ident::new("@namespace"), + Ident::new("stage_name/x@x~x%x+") + ])) + ) + } + _ => unreachable!(), + } } #[test] @@ -4231,4 +4251,4 @@ fn test_snowflake_create_view_with_composite_policy_name() { let create_view_with_tag = r#"CREATE VIEW X (COL WITH MASKING POLICY foo.bar.baz) AS SELECT * FROM Y"#; snowflake().verified_stmt(create_view_with_tag); -} +} \ No newline at end of file From 34011d8f62eb5f8edf48ab5f25539b0ff4db914b Mon Sep 17 00:00:00 2001 From: Yoav Cohen Date: Thu, 10 Jul 2025 04:46:20 +0200 Subject: [PATCH 2/2] Add support for + char in Snowflake stage names --- tests/sqlparser_snowflake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index c81d8950b..dd461d766 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -4251,4 +4251,4 @@ fn test_snowflake_create_view_with_composite_policy_name() { let create_view_with_tag = r#"CREATE VIEW X (COL WITH MASKING POLICY foo.bar.baz) AS SELECT * FROM Y"#; snowflake().verified_stmt(create_view_with_tag); -} \ No newline at end of file +}