Add Snowflake COPY/REVOKE CURRENT GRANTS option

This commit is contained in:
Yoav Cohen 2025-07-05 09:28:10 +02:00
parent ed8757f2f0
commit 1d02811ca8
4 changed files with 40 additions and 0 deletions

View file

@ -3996,6 +3996,7 @@ pub enum Statement {
with_grant_option: bool,
as_grantor: Option<Ident>,
granted_by: Option<Ident>,
current_grants: Option<CurrentGrantsKind>,
},
/// ```sql
/// DENY privileges ON object TO grantees
@ -4312,6 +4313,28 @@ pub enum Statement {
Return(ReturnStatement),
}
/// ```sql
/// {COPY | REVOKE} CURRENT GRANTS
/// ```
///
/// - [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/grant-ownership#optional-parameters)
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CurrentGrantsKind {
CopyCurrentGrants,
RevokeCurrentGrants,
}
impl fmt::Display for CurrentGrantsKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CurrentGrantsKind::CopyCurrentGrants => write!(f, "COPY CURRENT GRANTS"),
CurrentGrantsKind::RevokeCurrentGrants => write!(f, "REVOKE CURRENT GRANTS"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
@ -5715,6 +5738,7 @@ impl fmt::Display for Statement {
with_grant_option,
as_grantor,
granted_by,
current_grants,
} => {
write!(f, "GRANT {privileges} ")?;
if let Some(objects) = objects {
@ -5724,6 +5748,9 @@ impl fmt::Display for Statement {
if *with_grant_option {
write!(f, " WITH GRANT OPTION")?;
}
if let Some(current_grants) = current_grants {
write!(f, " {current_grants}")?;
}
if let Some(grantor) = as_grantor {
write!(f, " AS {grantor}")?;
}

View file

@ -13794,6 +13794,15 @@ impl<'a> Parser<'a> {
let with_grant_option =
self.parse_keywords(&[Keyword::WITH, Keyword::GRANT, Keyword::OPTION]);
let current_grants =
if self.parse_keywords(&[Keyword::COPY, Keyword::CURRENT, Keyword::GRANTS]) {
Some(CurrentGrantsKind::CopyCurrentGrants)
} else if self.parse_keywords(&[Keyword::REVOKE, Keyword::CURRENT, Keyword::GRANTS]) {
Some(CurrentGrantsKind::RevokeCurrentGrants)
} else {
None
};
let as_grantor = if self.parse_keywords(&[Keyword::AS]) {
Some(self.parse_identifier()?)
} else {
@ -13813,6 +13822,7 @@ impl<'a> Parser<'a> {
with_grant_option,
as_grantor,
granted_by,
current_grants,
})
}

View file

@ -9437,6 +9437,8 @@ fn parse_grant() {
verified_stmt("GRANT USAGE ON SCHEMA sc1 TO a:b");
verified_stmt("GRANT USAGE ON SCHEMA sc1 TO GROUP group1");
verified_stmt("GRANT OWNERSHIP ON ALL TABLES IN SCHEMA DEV_STAS_ROGOZHIN TO ROLE ANALYST");
verified_stmt("GRANT OWNERSHIP ON ALL TABLES IN SCHEMA DEV_STAS_ROGOZHIN TO ROLE ANALYST COPY CURRENT GRANTS");
verified_stmt("GRANT OWNERSHIP ON ALL TABLES IN SCHEMA DEV_STAS_ROGOZHIN TO ROLE ANALYST REVOKE CURRENT GRANTS");
verified_stmt("GRANT USAGE ON DATABASE db1 TO ROLE role1");
verified_stmt("GRANT USAGE ON WAREHOUSE wh1 TO ROLE role1");
verified_stmt("GRANT OWNERSHIP ON INTEGRATION int1 TO ROLE role1");

View file

@ -3616,6 +3616,7 @@ fn parse_grant() {
with_grant_option,
as_grantor: _,
granted_by,
current_grants: _,
} = stmt
{
assert_eq!(