From 421060bf34c3a8daeab0a130d7fde68b3177a84e Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Thu, 12 Oct 2023 19:28:41 +0300 Subject: [PATCH 1/3] allow number as placeholder --- src/parser/mod.rs | 1 + tests/sqlparser_snowflake.rs | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 95f1f8edc..89a2dc507 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -5208,6 +5208,7 @@ impl<'a> Parser<'a> { let next_token = self.next_token(); match next_token.token { Token::Word(w) => Ok(w.to_ident()), + Token::Number(w, false) => Ok(Ident::new(w)), Token::SingleQuotedString(s) => Ok(Ident::with_quote('\'', s)), Token::DoubleQuotedString(s) => Ok(Ident::with_quote('\"', s)), _ => self.expected("identifier", next_token), diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index e92656d0b..9589326af 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -1064,3 +1064,13 @@ fn test_snowflake_trim() { snowflake().parse_sql_statements(error_sql).unwrap_err() ); } + +#[test] +fn test_number_placehilder() { + let sql_only_select = "SELECT :1"; + let select = snowflake().verified_only_select(sql_only_select); + assert_eq!( + &Expr::Value(Value::Placeholder(":1".into())), + expr_from_projection(only(&select.projection)) + ); +} From d0e5603bf5c082a5dd075cec1c2680d4f42401eb Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Wed, 25 Oct 2023 14:06:52 +0300 Subject: [PATCH 2/3] CR Review --- src/parser/mod.rs | 10 ++++++++-- tests/sqlparser_snowflake.rs | 6 +++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 89a2dc507..19528badd 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -4654,7 +4654,14 @@ impl<'a> Parser<'a> { Token::HexStringLiteral(ref s) => Ok(Value::HexStringLiteral(s.to_string())), Token::Placeholder(ref s) => Ok(Value::Placeholder(s.to_string())), tok @ Token::Colon | tok @ Token::AtSign => { - let ident = self.parse_identifier()?; + // Not calling self.parse_identifier()? because only in placeholder we want to check numbers as idfentifies + // This because snowflake allows numbers as + let next_token = self.next_token(); + let ident = match next_token.token { + Token::Word(w) => Ok(w.to_ident()), + Token::Number(w, false) => Ok(Ident::new(w)), + _ => self.expected("placeholder", next_token), + }?; let placeholder = tok.to_string() + &ident.value; Ok(Value::Placeholder(placeholder)) } @@ -5208,7 +5215,6 @@ impl<'a> Parser<'a> { let next_token = self.next_token(); match next_token.token { Token::Word(w) => Ok(w.to_ident()), - Token::Number(w, false) => Ok(Ident::new(w)), Token::SingleQuotedString(s) => Ok(Ident::with_quote('\'', s)), Token::DoubleQuotedString(s) => Ok(Ident::with_quote('\"', s)), _ => self.expected("identifier", next_token), diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index 9589326af..54ece8f30 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -1066,11 +1066,15 @@ fn test_snowflake_trim() { } #[test] -fn test_number_placehilder() { +fn test_number_placeholder() { let sql_only_select = "SELECT :1"; let select = snowflake().verified_only_select(sql_only_select); assert_eq!( &Expr::Value(Value::Placeholder(":1".into())), expr_from_projection(only(&select.projection)) ); + + snowflake() + .parse_sql_statements("alter role 1 with name = 'foo'") + .expect_err("should have failed"); } From b68dfe797714a0d7fccd1deb0d1771ef364e90d9 Mon Sep 17 00:00:00 2001 From: Yuval Shkolar Date: Wed, 25 Oct 2023 14:11:46 +0300 Subject: [PATCH 3/3] comment --- src/parser/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 82c9ef339..45ce81ac0 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -4760,7 +4760,7 @@ impl<'a> Parser<'a> { Token::Placeholder(ref s) => Ok(Value::Placeholder(s.to_string())), tok @ Token::Colon | tok @ Token::AtSign => { // Not calling self.parse_identifier()? because only in placeholder we want to check numbers as idfentifies - // This because snowflake allows numbers as + // This because snowflake allows numbers as placeholders let next_token = self.next_token(); let ident = match next_token.token { Token::Word(w) => Ok(w.to_ident()),