diff --git a/docs/cn/sql-reference/10-sql-commands/00-ddl/01-table/90-alter-table-column.md b/docs/cn/sql-reference/10-sql-commands/00-ddl/01-table/90-alter-table-column.md index b91f5703ea..f704d85480 100644 --- a/docs/cn/sql-reference/10-sql-commands/00-ddl/01-table/90-alter-table-column.md +++ b/docs/cn/sql-reference/10-sql-commands/00-ddl/01-table/90-alter-table-column.md @@ -65,6 +65,14 @@ DROP [ COLUMN ] - 尚不支持使用 ALTER TABLE 添加存储计算列。 - 当更改表列的数据类型(Data Type)时,存在转换错误的风险。例如,如果尝试将文本(String)列转换为数字(Float)列,可能会引发问题。 - 当为列设置脱敏策略(Masking Policy)时,请确保策略中定义的数据类型(请参考 [CREATE MASKING POLICY](../12-mask-policy/create-mask-policy.md) 语法中的 *arg_type_to_mask* 参数)与列的数据类型相匹配。 +- 如果策略需要额外的列,可结合 `USING` 子句使用,按照参数顺序列出对应的列;第一个参数始终代表正在脱敏的列。 +- 当声明了 `USING (...)` 时,必须至少提供被脱敏的列以及策略所需的其他列,并确保 `USING` 中的第一个标识符与正在修改的列一致。 +- 只有常规表支持绑定脱敏策略;视图、流表以及临时表均无法执行 `SET MASKING POLICY`。 +- 单个列最多只能附加一个安全策略(无论是列脱敏还是行级策略)。在重新绑定之前,请先移除原有策略。 +::: + +:::caution +如果列已绑定脱敏策略,修改列定义或删除该列前必须先执行 `ALTER TABLE ... MODIFY COLUMN UNSET MASKING POLICY`,否则操作会因安全策略仍然生效而失败。 ::: ## 示例 @@ -280,4 +288,4 @@ id|email | --+---------+ 2|*********| 1|*********| -``` \ No newline at end of file +``` diff --git a/docs/cn/sql-reference/10-sql-commands/00-ddl/12-mask-policy/create-mask-policy.md b/docs/cn/sql-reference/10-sql-commands/00-ddl/12-mask-policy/create-mask-policy.md index 52c4d785f0..91b0f21b5e 100644 --- a/docs/cn/sql-reference/10-sql-commands/00-ddl/12-mask-policy/create-mask-policy.md +++ b/docs/cn/sql-reference/10-sql-commands/00-ddl/12-mask-policy/create-mask-policy.md @@ -22,21 +22,23 @@ CREATE [ OR REPLACE ] MASKING POLICY [ IF NOT EXISTS ] AS [ COMMENT = '' ] ``` -| 参数 | 描述 | -|------------------------ |--------------------------------------------------------------------------------------------------------------------------------------- | -| policy_name | 要创建的脱敏策略的名称。 | -| arg_name_to_mask | 需要脱敏的原始数据参数的名称。 | -| arg_type_to_mask | 要脱敏的原始数据参数的数据类型。 | -| expression_on_arg_name | 一个表达式,用于确定如何处理原始数据以生成脱敏数据。 | -| comment | 提供有关脱敏策略信息或说明的可选注释。 | +| 参数 | 描述 | +|------|------| +| `policy_name` | 要创建的脱敏策略名称。 | +| `arg_name_to_mask` | 表示被脱敏列的参数。该参数必须放在第一位,并自动绑定到 `SET MASKING POLICY` 中指向的列。 | +| `arg_type_to_mask` | 被脱敏列的数据类型,必须与实际列一致。 | +| `arg_1 ... arg_n` | 策略逻辑需要的可选额外列参数。绑定策略时,通过 `USING` 子句提供这些列。 | +| `arg_type_1 ... arg_type_n` | 每个额外参数对应的数据类型,需要与 `USING` 子句中的列匹配。 | +| `expression_on_arg_name` | 描述如何处理输入列以生成脱敏结果的表达式。 | +| `comment` | 可选注释,用于补充策略说明。 | :::note -确保 *arg_type_to_mask* 与将应用脱敏策略的列的数据类型匹配。 +确保 *arg_type_to_mask* 与将应用脱敏策略的列的数据类型匹配。当策略包含多个参数时,必须在 `ALTER TABLE ... SET MASKING POLICY` 的 `USING` 子句中按相同顺序列出对应列。 ::: ## 示例 -此示例演示了设置脱敏策略以根据用户角色选择性地显示或脱敏敏感数据的过程。 +此示例演示了如何结合 `USING` 子句引用额外列,根据用户角色或其他列的值选择性地显示或脱敏敏感数据。 ```sql -- 创建表并插入示例数据 @@ -57,37 +59,33 @@ GRANT ALL ON *.* TO ROLE 'MANAGERS'; CREATE USER manager_user IDENTIFIED BY 'databend'; GRANT ROLE 'MANAGERS' TO 'manager_user'; --- 创建脱敏策略 -CREATE MASKING POLICY email_mask +-- 创建需要额外列参与判断的脱敏策略 +CREATE MASKING POLICY contact_mask AS - (val nullable(string)) + (contact_val nullable(string), phone_ref nullable(string)) RETURNS nullable(string) -> CASE - WHEN current_role() IN ('MANAGERS') THEN - val - ELSE - '*********' + WHEN current_role() IN ('MANAGERS') THEN contact_val + WHEN phone_ref LIKE '91%' THEN contact_val + ELSE '*********' END - COMMENT = 'hide_email'; + COMMENT = 'mask contact data with phone check'; -CREATE MASKING POLICY phone_mask AS (val nullable(string)) RETURNS nullable(string) -> CASE - WHEN current_role() IN ('MANAGERS') THEN val - ELSE '*********' -END COMMENT = 'hide_phone'; +-- 将脱敏策略与 'email' 列关联,并通过 USING 传入额外列 +ALTER TABLE user_info +MODIFY COLUMN email SET MASKING POLICY contact_mask USING (email, phone); --- 将脱敏策略与 'email' 列关联 -ALTER TABLE user_info MODIFY COLUMN email SET MASKING POLICY email_mask; - --- 将脱敏策略与 'phone' 列关联 -ALTER TABLE user_info MODIFY COLUMN phone SET MASKING POLICY phone_mask; +-- 将脱敏策略与 'phone' 列关联(此处同样传递自身和参考列) +ALTER TABLE user_info +MODIFY COLUMN phone SET MASKING POLICY contact_mask USING (phone, phone); -- 使用 Root 用户查询 -SELECT * FROM user_info; +SELECT user_id, phone, email FROM user_info ORDER BY user_id; user_id │ phone │ email │ Nullable(Int32) │ Nullable(String) │ Nullable(String) │ ─────────────────┼──────────────────┼──────────────────┤ + 1 │ 91234567 │ sue@example.com │ 2 │ ********* │ ********* │ - 1 │ ********* │ ********* │ -``` \ No newline at end of file +``` diff --git a/docs/en/sql-reference/10-sql-commands/00-ddl/01-table/90-alter-table-column.md b/docs/en/sql-reference/10-sql-commands/00-ddl/01-table/90-alter-table-column.md index eb52f5bb11..a606825104 100644 --- a/docs/en/sql-reference/10-sql-commands/00-ddl/01-table/90-alter-table-column.md +++ b/docs/en/sql-reference/10-sql-commands/00-ddl/01-table/90-alter-table-column.md @@ -50,6 +50,7 @@ MODIFY [ COLUMN ] [ COMMENT '' ] -- Set / Unset masking policy for a column ALTER TABLE [ IF EXISTS ] [ . ] MODIFY [ COLUMN ] SET MASKING POLICY + [ USING ( [ , ... ] ) ] ALTER TABLE [ IF EXISTS ] [ . ] MODIFY [ COLUMN ] UNSET MASKING POLICY @@ -64,6 +65,14 @@ DROP [ COLUMN ] - Adding a stored computed column with ALTER TABLE is not supported yet. - When you change the data type of a table's columns, there's a risk of conversion errors. For example, if you try to convert a column with text (String) to numbers (Float), it might cause problems. - When you set a masking policy for a column, make sure that the data type (refer to the parameter *arg_type_to_mask* in the syntax of [CREATE MASKING POLICY](../12-mask-policy/create-mask-policy.md)) defined in the policy matches the column. +- Use the optional `USING` clause when the policy definition expects additional parameters. List the column mapped to each policy argument in order; the first argument always represents the column being masked. +- If you include `USING`, provide at least the masked column plus any additional columns needed by the policy. The first identifier in `USING (...)` must match the column being modified. +- Masking policies can only be attached to regular tables. Views, streams, and temporary tables do not allow `SET MASKING POLICY`. +- A column can belong to at most one security policy (masking or row-level). Remove the existing policy before attaching a new one. +::: + +:::caution +You must `ALTER TABLE ... MODIFY COLUMN UNSET MASKING POLICY` before changing the column definition or dropping the column; otherwise the statement fails because the column is still protected by a security policy. ::: ## Examples @@ -234,19 +243,20 @@ SHOW CREATE TABLE students_info; └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ``` -### Example 5: Setting Masking Policy for a Column +### Example 5: Setting a Masking Policy with the USING Clause -This example illustrates the process of setting up a masking policy to selectively reveal or mask sensitive data based on user roles. +This example illustrates how to set up a masking policy that references additional columns by using the `USING` clause. ```sql -- Create a table and insert sample data CREATE TABLE user_info ( id INT, + phone STRING, email STRING ); -INSERT INTO user_info (id, email) VALUES (1, 'sue@example.com'); -INSERT INTO user_info (id, email) VALUES (2, 'eric@example.com'); +INSERT INTO user_info (id, phone, email) VALUES (1, '91234567', 'sue@example.com'); +INSERT INTO user_info (id, phone, email) VALUES (2, '81234567', 'eric@example.com'); -- Create a role CREATE ROLE 'MANAGERS'; @@ -256,27 +266,28 @@ GRANT ALL ON *.* TO ROLE 'MANAGERS'; CREATE USER manager_user IDENTIFIED BY 'databend'; GRANT ROLE 'MANAGERS' TO 'manager_user'; --- Create a masking policy +-- Create a masking policy that inspects another column CREATE MASKING POLICY email_mask AS - (val string) - RETURNS string -> + (email_val nullable(string), phone_ref nullable(string)) + RETURNS nullable(string) -> CASE - WHEN current_role() IN ('MANAGERS') THEN - val - ELSE - '*********' + WHEN current_role() IN ('MANAGERS') THEN email_val + WHEN phone_ref LIKE '91%' THEN email_val + ELSE '*********' END - COMMENT = 'hide_email'; + COMMENT = 'hide_email_when_phone_is_masked'; --- Associate the masking policy with the 'email' column -ALTER TABLE user_info MODIFY COLUMN email SET MASKING POLICY email_mask; +-- Associate the masking policy with the 'email' column and provide +-- the additional column required by the policy by using USING(...) +ALTER TABLE user_info +MODIFY COLUMN email SET MASKING POLICY email_mask USING (email, phone); -- Query with the Root user -SELECT * FROM user_info; +SELECT id, phone, email FROM user_info ORDER BY id; -id|email | ---+---------+ - 2|*********| - 1|*********| +id|phone |email | +--+--------+---------------+ + 1|91234567|sue@example.com| + 2|81234567|********* | ``` diff --git a/docs/en/sql-reference/10-sql-commands/00-ddl/12-mask-policy/create-mask-policy.md b/docs/en/sql-reference/10-sql-commands/00-ddl/12-mask-policy/create-mask-policy.md index 117c260c9e..16664dce8d 100644 --- a/docs/en/sql-reference/10-sql-commands/00-ddl/12-mask-policy/create-mask-policy.md +++ b/docs/en/sql-reference/10-sql-commands/00-ddl/12-mask-policy/create-mask-policy.md @@ -22,16 +22,18 @@ CREATE [ OR REPLACE ] MASKING POLICY [ IF NOT EXISTS ] AS [ COMMENT = '' ] ``` -| Parameter | Description | -|------------------------ |--------------------------------------------------------------------------------------------------------------------------------------- | -| policy_name | The name of the masking policy to be created. | -| arg_name_to_mask | The name of the original data parameter that needs to be masked. | -| arg_type_to_mask | The data type of the original data parameter to be masked. | -| expression_on_arg_name | An expression that determines how the original data should be treated to generate the masked data. | -| comment | An optional comment providing information or notes about the masking policy. | +| Parameter | Description | +|------------------------|-------------| +| `policy_name` | Name of the masking policy to be created. | +| `arg_name_to_mask` | Parameter that represents the column being masked. This argument must appear first and automatically binds to the column referenced in `SET MASKING POLICY`. | +| `arg_type_to_mask` | Data type of the masked column. It must match the data type of the column where the policy is applied. | +| `arg_1 ... arg_n` | Optional extra parameters for additional columns that the policy logic depends on. Provide these columns through the `USING` clause when you attach the policy. | +| `arg_type_1 ... arg_type_n` | Data types for each optional parameter. They must match the columns listed in the `USING` clause. | +| `expression_on_arg_name` | Expression that determines how the input columns should be treated to generate the masked data. | +| `comment` | Optional comment that stores notes about the masking policy. | :::note -Ensure that *arg_type_to_mask* matches the data type of the column where the masking policy will be applied. +Ensure that *arg_type_to_mask* matches the data type of the column where the masking policy will be applied. When your policy defines multiple parameters, list each referenced column in the same order within the `USING` clause of `ALTER TABLE ... SET MASKING POLICY`. ::: ## Examples @@ -57,37 +59,37 @@ GRANT ALL ON *.* TO ROLE 'MANAGERS'; CREATE USER manager_user IDENTIFIED BY 'databend'; GRANT ROLE 'MANAGERS' TO 'manager_user'; --- Create a masking policy -CREATE MASKING POLICY email_mask +-- Create a masking policy that expects an extra column +CREATE MASKING POLICY contact_mask AS - (val nullable(string)) + (contact_val nullable(string), phone_ref nullable(string)) RETURNS nullable(string) -> CASE WHEN current_role() IN ('MANAGERS') THEN - val + contact_val + WHEN phone_ref LIKE '91%' + THEN + contact_val ELSE '*********' END - COMMENT = 'hide_email'; - -CREATE MASKING POLICY phone_mask AS (val nullable(string)) RETURNS nullable(string) -> CASE - WHEN current_role() IN ('MANAGERS') THEN val - ELSE '*********' -END COMMENT = 'hide_phone'; + COMMENT = 'mask contact data with phone check'; -- Associate the masking policy with the 'email' column -ALTER TABLE user_info MODIFY COLUMN email SET MASKING POLICY email_mask; +ALTER TABLE user_info +MODIFY COLUMN email SET MASKING POLICY contact_mask USING (email, phone); -- Associate the masking policy with the 'phone' column -ALTER TABLE user_info MODIFY COLUMN phone SET MASKING POLICY phone_mask; +ALTER TABLE user_info +MODIFY COLUMN phone SET MASKING POLICY contact_mask USING (phone, phone); -- Query with the Root user -SELECT * FROM user_info; +SELECT user_id, phone, email FROM user_info ORDER BY user_id; user_id │ phone │ email │ Nullable(Int32) │ Nullable(String) │ Nullable(String) │ ─────────────────┼──────────────────┼──────────────────┤ + 1 │ 91234567 │ sue@example.com │ 2 │ ********* │ ********* │ - 1 │ ********* │ ********* │ ```