Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,61 @@ pub enum AlterColumnOperation {
/// Optional sequence options for identity generation.
sequence_options: Option<Vec<SequenceOptions>>,
},

/// `SET MASKING POLICY <policy> [USING (<col>, ...)] [FORCE]`
///
/// Snowflake: attach a masking policy to the column
/// (`ALTER TABLE t MODIFY COLUMN c SET MASKING POLICY p`).
SetMaskingPolicy {
/// The policy to attach.
policy_name: ObjectName,
/// Optional `USING (<col>, ...)` conditional-masking column list.
using_columns: Option<Vec<Ident>>,
/// Whether the `FORCE` keyword was present.
force: bool,
},

/// `UNSET MASKING POLICY`
///
/// Snowflake: detach the masking policy from the column.
UnsetMaskingPolicy,
}

/// An operation on a masking policy in an `ALTER MASKING POLICY` statement.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterMaskingPolicyOperation {
/// `SET BODY -> <expr>`
SetBody {
/// The replacement body expression.
body: Expr,
},
/// `RENAME TO <name>`
RenameTo {
/// The new policy name.
new_name: ObjectName,
},
/// `SET COMMENT = '<comment>'`
SetComment {
/// The replacement comment text.
comment: String,
},
/// `UNSET COMMENT`
UnsetComment,
}

impl fmt::Display for AlterMaskingPolicyOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterMaskingPolicyOperation::SetBody { body } => write!(f, "SET BODY -> {body}"),
AlterMaskingPolicyOperation::RenameTo { new_name } => write!(f, "RENAME TO {new_name}"),
AlterMaskingPolicyOperation::SetComment { comment } => {
write!(f, "SET COMMENT = '{}'", escape_single_quote_string(comment))
}
AlterMaskingPolicyOperation::UnsetComment => write!(f, "UNSET COMMENT"),
}
}
}

impl fmt::Display for AlterColumnOperation {
Expand Down Expand Up @@ -1408,6 +1463,21 @@ impl fmt::Display for AlterColumnOperation {
}
Ok(())
}
AlterColumnOperation::SetMaskingPolicy {
policy_name,
using_columns,
force,
} => {
write!(f, "SET MASKING POLICY {policy_name}")?;
if let Some(columns) = using_columns {
write!(f, " USING ({})", display_comma_separated(columns))?;
}
if *force {
write!(f, " FORCE")?;
}
Ok(())
}
AlterColumnOperation::UnsetMaskingPolicy => write!(f, "UNSET MASKING POLICY"),
}
}
}
Expand Down
128 changes: 128 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub use self::dcl::{
pub use self::ddl::{
Alignment, AlterCollation, AlterCollationOperation, AlterColumnOperation, AlterConnectorOwner,
AlterFunction, AlterFunctionAction, AlterFunctionKind, AlterFunctionOperation,
AlterMaskingPolicyOperation,
AlterIndexOperation, AlterProcedure, AlterProcedureOperation,
AlterOperator, AlterOperatorClass, AlterOperatorClassOperation,
AlterOperatorFamily, AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy,
Expand Down Expand Up @@ -4148,6 +4149,20 @@ pub enum Statement {
with_options: Vec<SqlOption>,
},
/// ```sql
/// ALTER VIEW <name> { MODIFY | ALTER } COLUMN <col>
/// { SET MASKING POLICY <p> [USING (<c>, ...)] [FORCE] | UNSET MASKING POLICY }
/// ```
/// Snowflake column-level masking-policy operation on a view.
AlterViewColumn {
/// View name.
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
name: ObjectName,
/// Target column.
column_name: Ident,
/// The column operation to apply.
op: AlterColumnOperation,
},
/// ```sql
/// ALTER FUNCTION
/// ALTER AGGREGATE
/// ```
Expand Down Expand Up @@ -5381,6 +5396,63 @@ pub enum Statement {
filter: Option<ShowStatementFilter>,
},
/// ```sql
/// CREATE [OR REPLACE] MASKING POLICY [IF NOT EXISTS] <name>
/// AS (<arg> <type>[, ...]) RETURNS <type> -> <body> [COMMENT = '<comment>']
/// ```
/// See <https://docs.snowflake.com/en/sql-reference/sql/create-masking-policy>
CreateMaskingPolicy {
/// `OR REPLACE` flag.
or_replace: bool,
/// `IF NOT EXISTS` flag.
if_not_exists: bool,
/// Policy name.
name: ObjectName,
/// Signature arguments (name + type), in declaration order.
args: Vec<OperateFunctionArg>,
/// The declared return type.
return_type: DataType,
/// The policy body expression after `->`.
policy_expr: Expr,
/// Optional `COMMENT = '<comment>'`.
comment: Option<String>,
},
/// ```sql
/// ALTER MASKING POLICY [IF EXISTS] <name>
/// { SET BODY -> <expr> | RENAME TO <name> | SET COMMENT = '<comment>' | UNSET COMMENT }
/// ```
/// See <https://docs.snowflake.com/en/sql-reference/sql/alter-masking-policy>
AlterMaskingPolicy {
/// `IF EXISTS` flag.
if_exists: bool,
/// Policy name.
name: ObjectName,
/// The operation to apply.
operation: AlterMaskingPolicyOperation,
},
/// ```sql
/// DROP MASKING POLICY [IF EXISTS] <name>
/// ```
DropMaskingPolicy {
/// `IF EXISTS` flag.
if_exists: bool,
/// Policy name.
name: ObjectName,
},
/// ```sql
/// DESC[RIBE] MASKING POLICY <name>
/// ```
DescribeMaskingPolicy {
/// Policy name.
name: ObjectName,
},
/// ```sql
/// SHOW MASKING POLICIES [ LIKE '<pattern>' ] [ IN <scope> ]
/// ```
ShowMaskingPolicies {
/// Options controlling the SHOW output (filter, `IN <scope>`, etc.).
show_options: ShowStatementOptions,
},
/// ```sql
/// SHOW PROCEDURES [ LIKE '<pattern>' ] [ IN <scope> ]
/// ```
ShowProcedures {
Expand Down Expand Up @@ -6746,6 +6818,13 @@ impl fmt::Display for Statement {
}
write!(f, " AS {query}")
}
Statement::AlterViewColumn {
name,
column_name,
op,
} => {
write!(f, "ALTER VIEW {name} ALTER COLUMN {column_name} {op}")
}
Statement::AlterFunction(alter_function) => write!(f, "{alter_function}"),
Statement::AlterType(AlterType { name, operation }) => {
write!(f, "ALTER TYPE {name} {operation}")
Expand Down Expand Up @@ -7835,6 +7914,55 @@ impl fmt::Display for Statement {
}
Ok(())
}
Statement::CreateMaskingPolicy {
or_replace,
if_not_exists,
name,
args,
return_type,
policy_expr,
comment,
} => {
write!(
f,
"CREATE {or_replace}MASKING POLICY {if_not_exists}{name} AS ({args}) RETURNS {return_type} -> {policy_expr}",
or_replace = if *or_replace { "OR REPLACE " } else { "" },
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
args = display_comma_separated(args),
)?;
if let Some(comment) = comment {
write!(
f,
" COMMENT = '{}'",
value::escape_single_quote_string(comment)
)?;
}
Ok(())
}
Statement::AlterMaskingPolicy {
if_exists,
name,
operation,
} => {
write!(
f,
"ALTER MASKING POLICY {if_exists}{name} {operation}",
if_exists = if *if_exists { "IF EXISTS " } else { "" },
)
}
Statement::DropMaskingPolicy { if_exists, name } => {
write!(
f,
"DROP MASKING POLICY {if_exists}{name}",
if_exists = if *if_exists { "IF EXISTS " } else { "" },
)
}
Statement::DescribeMaskingPolicy { name } => {
write!(f, "DESCRIBE MASKING POLICY {name}")
}
Statement::ShowMaskingPolicies { show_options } => {
write!(f, "SHOW MASKING POLICIES{show_options}")
}
Statement::ShowProcedures { show_options } => {
write!(f, "SHOW PROCEDURES{show_options}")?;
Ok(())
Expand Down
14 changes: 14 additions & 0 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,13 @@ impl Spanned for Statement {
.chain(core::iter::once(query.span()))
.chain(with_options.iter().map(|i| i.span())),
),
Statement::AlterViewColumn {
name,
column_name,
op,
} => union_spans(
[name.span(), column_name.span, op.span()].into_iter(),
),
// These statements need to be implemented
Statement::AlterFunction { .. } => Span::empty(),
Statement::AlterType { .. } => Span::empty(),
Expand Down Expand Up @@ -570,6 +577,11 @@ impl Spanned for Statement {
Statement::DropRowAccessPolicy { .. } => Span::empty(),
Statement::DescribeRowAccessPolicy { .. } => Span::empty(),
Statement::ShowRowAccessPolicies { .. } => Span::empty(),
Statement::CreateMaskingPolicy { .. } => Span::empty(),
Statement::AlterMaskingPolicy { .. } => Span::empty(),
Statement::DropMaskingPolicy { .. } => Span::empty(),
Statement::DescribeMaskingPolicy { .. } => Span::empty(),
Statement::ShowMaskingPolicies { .. } => Span::empty(),
Statement::ShowProcedures { .. } => Span::empty(),
Statement::ShowConnections { .. } => Span::empty(),
Statement::ShowShares { .. } => Span::empty(),
Expand Down Expand Up @@ -1024,6 +1036,8 @@ impl Spanned for AlterColumnOperation {
} => using.as_ref().map_or(Span::empty(), |u| u.span()),
AlterColumnOperation::Comment { .. } => Span::empty(),
AlterColumnOperation::AddGenerated { .. } => Span::empty(),
AlterColumnOperation::SetMaskingPolicy { .. } => Span::empty(),
AlterColumnOperation::UnsetMaskingPolicy => Span::empty(),
}
}
}
Expand Down
Loading
Loading