Skip to content

Commit 45a832c

Browse files
committed
fix: parse snowflake fetch clause
1 parent b1b379e commit 45a832c

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
@@ -15018,6 +15018,9 @@ impl<'a> Parser<'a> {
1501815018

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

15050+
/// Parse a FETCH clause with Snowflake-specific syntax
15051+
fn parse_snowflake_fetch(&mut self) -> Result<Fetch, ParserError> {
15052+
// Snowflake: All additional keywords are optional. WITH TIES is not allowed.
15053+
let _ = self.parse_one_of_keywords(&[Keyword::FIRST, Keyword::NEXT]);
15054+
15055+
let quantity = Expr::Value(self.parse_value()?);
15056+
let _ = self.parse_one_of_keywords(&[Keyword::ROW, Keyword::ROWS]);
15057+
let _ = self.parse_keyword(Keyword::ONLY);
15058+
15059+
Ok(Fetch {
15060+
with_ties: false,
15061+
percent: false,
15062+
quantity: Some(quantity),
15063+
})
15064+
}
15065+
1504715066
/// Parse a FOR UPDATE/FOR SHARE clause
1504815067
pub fn parse_lock(&mut self) -> Result<LockClause, ParserError> {
1504915068
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
@@ -4082,3 +4082,36 @@ fn parse_connect_by_root_operator() {
40824082
"sql parser error: Expected an expression, found: FROM"
40834083
);
40844084
}
4085+
4086+
#[test]
4087+
fn test_snowflake_fetch_clause_syntax() {
4088+
let canonical = "SELECT c1 FROM fetch_test FETCH FIRST 2 ROWS ONLY";
4089+
snowflake().verified_only_select_with_canonical("SELECT c1 FROM fetch_test FETCH 2", canonical);
4090+
4091+
snowflake()
4092+
.verified_only_select_with_canonical("SELECT c1 FROM fetch_test FETCH FIRST 2", canonical);
4093+
snowflake()
4094+
.verified_only_select_with_canonical("SELECT c1 FROM fetch_test FETCH NEXT 2", canonical);
4095+
4096+
snowflake()
4097+
.verified_only_select_with_canonical("SELECT c1 FROM fetch_test FETCH 2 ROW", canonical);
4098+
4099+
snowflake().verified_only_select_with_canonical(
4100+
"SELECT c1 FROM fetch_test FETCH FIRST 2 ROWS",
4101+
canonical,
4102+
);
4103+
4104+
snowflake()
4105+
.verified_only_select_with_canonical("SELECT c1 FROM fetch_test FETCH 2 ONLY", canonical);
4106+
let res = snowflake().parse_sql_statements("SELECT c1 FROM fetch_test FETCH 2 PERCENT");
4107+
assert_eq!(
4108+
res.unwrap_err().to_string(),
4109+
"sql parser error: Expected: end of statement, found: PERCENT"
4110+
);
4111+
let res =
4112+
snowflake().parse_sql_statements("SELECT c1 FROM fetch_test FETCH FIRST 2 ROWS WITH TIES");
4113+
assert_eq!(
4114+
res.unwrap_err().to_string(),
4115+
"sql parser error: Expected: end of statement, found: WITH"
4116+
);
4117+
}

0 commit comments

Comments
 (0)