Skip to content

Commit 020f922

Browse files
committed
fix: parse snowflake fetch clause
1 parent 7865de0 commit 020f922

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

src/parser/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15017,6 +15017,9 @@ impl<'a> Parser<'a> {
1501715017

1501815018
/// Parse a FETCH clause
1501915019
pub fn parse_fetch(&mut self) -> Result<Fetch, ParserError> {
15020+
if dialect_of!(self is SnowflakeDialect) {
15021+
return self.parse_snowflake_fetch();
15022+
}
1502015023
self.expect_one_of_keywords(&[Keyword::FIRST, Keyword::NEXT])?;
1502115024
let (quantity, percent) = if self
1502215025
.parse_one_of_keywords(&[Keyword::ROW, Keyword::ROWS])
@@ -15043,6 +15046,22 @@ impl<'a> Parser<'a> {
1504315046
})
1504415047
}
1504515048

15049+
/// Parse a FETCH clause with Snowflake-specific syntax
15050+
fn parse_snowflake_fetch(&mut self) -> Result<Fetch, ParserError> {
15051+
// Snowflake: All additional keywords are optional. WITH TIES is not allowed.
15052+
let _ = self.parse_one_of_keywords(&[Keyword::FIRST, Keyword::NEXT]);
15053+
15054+
let quantity = Expr::Value(self.parse_value()?);
15055+
let _ = self.parse_one_of_keywords(&[Keyword::ROW, Keyword::ROWS]);
15056+
let _ = self.parse_keyword(Keyword::ONLY);
15057+
15058+
Ok(Fetch {
15059+
with_ties: false,
15060+
percent: false,
15061+
quantity: Some(quantity),
15062+
})
15063+
}
15064+
1504615065
/// Parse a FOR UPDATE/FOR SHARE clause
1504715066
pub fn parse_lock(&mut self) -> Result<LockClause, ParserError> {
1504815067
let lock_type = match self.expect_one_of_keywords(&[Keyword::UPDATE, Keyword::SHARE])? {

tests/sqlparser_snowflake.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4146,3 +4146,36 @@ END
41464146
assert_eq!(2, exception[1].idents.len());
41474147
assert_eq!(2, exception[1].statements.len());
41484148
}
4149+
4150+
#[test]
4151+
fn test_snowflake_fetch_clause_syntax() {
4152+
let canonical = "SELECT c1 FROM fetch_test FETCH FIRST 2 ROWS ONLY";
4153+
snowflake().verified_only_select_with_canonical("SELECT c1 FROM fetch_test FETCH 2", canonical);
4154+
4155+
snowflake()
4156+
.verified_only_select_with_canonical("SELECT c1 FROM fetch_test FETCH FIRST 2", canonical);
4157+
snowflake()
4158+
.verified_only_select_with_canonical("SELECT c1 FROM fetch_test FETCH NEXT 2", canonical);
4159+
4160+
snowflake()
4161+
.verified_only_select_with_canonical("SELECT c1 FROM fetch_test FETCH 2 ROW", canonical);
4162+
4163+
snowflake().verified_only_select_with_canonical(
4164+
"SELECT c1 FROM fetch_test FETCH FIRST 2 ROWS",
4165+
canonical,
4166+
);
4167+
4168+
snowflake()
4169+
.verified_only_select_with_canonical("SELECT c1 FROM fetch_test FETCH 2 ONLY", canonical);
4170+
let res = snowflake().parse_sql_statements("SELECT c1 FROM fetch_test FETCH 2 PERCENT");
4171+
assert_eq!(
4172+
res.unwrap_err().to_string(),
4173+
"sql parser error: Expected: end of statement, found: PERCENT"
4174+
);
4175+
let res =
4176+
snowflake().parse_sql_statements("SELECT c1 FROM fetch_test FETCH FIRST 2 ROWS WITH TIES");
4177+
assert_eq!(
4178+
res.unwrap_err().to_string(),
4179+
"sql parser error: Expected: end of statement, found: WITH"
4180+
);
4181+
}

0 commit comments

Comments
 (0)