管理访问策略

默认情况下,您只能管理您拥有的表的访问策略。您可以选择使用 AccessPolicyManagementSuperuserOnly 参数(默认值为 false)仅允许超级用户管理访问策略:

=> ALTER DATABASE DEFAULT SET PARAMETER AccessPolicyManagementSuperuserOnly = 1;
ALTER DATABASE

您可以通过多种方式查看和管理表的访问策略:

查看访问策略

您可以通过两种方式查看访问策略:

  • 查询系统表 ACCESS_POLICY。例如,以下查询返回表 public.customer_dimension 上的所有访问策略:

    => \x
    => SELECT policy_type, is_policy_enabled, table_name, column_name, expression FROM access_policy WHERE table_name = 'public.customer_dimension';
    -[ RECORD 1 ]-----+----------------------------------------------------------------------------------------
    policy_type       | Column Policy
    is_policy_enabled | Enabled
    table_name        | public.customer_dimension
    column_name       | customer_address
    expression        | CASE WHEN enabled_role('administrator') THEN customer_address ELSE '**************' END
    

  • 使用 EXPORT_TABLESEXPORT_OBJECTSEXPORT_CATALOG 从数据库编录导出表 DDL。例如:

    => SELECT export_tables('','customer_dimension');
                                    export_tables
    -----------------------------------------------------------------------------
    CREATE TABLE public.customer_dimension
    (
        customer_key int NOT NULL,
        customer_type varchar(16),
        customer_name varchar(256),
        customer_gender varchar(8),
        ...
        CONSTRAINT C_PRIMARY PRIMARY KEY (customer_key) DISABLED
    );
    
    CREATE ACCESS POLICY ON public.customer_dimension FOR COLUMN customer_address CASE WHEN enabled_role('administrator') THEN customer_address ELSE '**************' END ENABLE;
    

修改访问策略表达式

ALTER ACCESS POLICY 可以修改现有访问策略的表达式。例如,您可以通过扩展对 dbadmin 角色的访问权限来修改前面示例中的访问策略:

=> ALTER ACCESS POLICY ON public.customer_dimension FOR COLUMN customer_address
    CASE WHEN enabled_role('dbadmin') THEN customer_address
         WHEN enabled_role('administrator') THEN customer_address
         ELSE '**************' END ENABLE;
ALTER ACCESS POLICY

查询系统表 ACCESS_POLICY 会确认此更改:

=> SELECT policy_type, is_policy_enabled, table_name, column_name, expression FROM access_policy
  WHERE table_name = 'public.customer_dimension' AND column_name='customer_address';
-[ RECORD 1 ]-----+-------------------------------------------------------------------------------------------------------------------------------------------
policy_type       | Column Policy
is_policy_enabled | Enabled
table_name        | public.customer_dimension
column_name       | customer_address
expression        | CASE WHEN enabled_role('dbadmin') THEN customer_address WHEN enabled_role('administrator') THEN customer_address ELSE '**************' END

启用和禁用访问策略

表的所有者可以启用和禁用表中的行和列访问策略。

行访问策略

启用和禁用表中的访问策略。

ALTER ACCESS POLICY ON [schema.]table FOR ROWS { ENABLE | DISABLE }

以下示例先禁用后重新启用表 customer_dimension 上的行访问策略:

=> ALTER ACCESS POLICY ON customer_dimension FOR ROWS DISABLE;
ALTER ACCESS POLICY
=> ALTER ACCESS POLICY ON customer_dimension FOR ROWS ENABLE;
ALTER ACCESS POLICY

列访问策略

按如下方式启用和禁用表列的访问策略:

ALTER ACCESS POLICY ON [schema.]table FOR COLUMN column { ENABLE | DISABLE }

以下示例先禁用后重新启用表 customer_dimension.customer_address 上的同一个列访问策略:

=> ALTER ACCESS POLICY ON public.customer_dimension FOR COLUMN customer_address DISABLE;
ALTER ACCESS POLICY
=> ALTER ACCESS POLICY ON public.customer_dimension FOR COLUMN customer_address ENABLE;
ALTER ACCESS POLICY

复制访问策略

按如下方式将访问策略从一个表复制到另一个表。非超级用户必须同时拥有源表和目标表的所有权:

ALTER ACCESS POLICY ON [schema.]table { FOR COLUMN column | FOR ROWS } COPY TO TABLE table

当您使用以下函数(而非 CREATE TABLE AS SELECT 或 CREATE TABLE LIKE)创建表的副本或移动其内容时,会将原始表的访问策略复制到新/目标表:

若要将访问策略复制到另一个表,请使用 ALTER ACCESS POLICY

例如,您可以按如下方式复制行访问策略:

=> ALTER ACCESS POLICY ON public.emp_dimension FOR ROWS COPY TO TABLE public.regional_managers_dimension;

以下语句将列 employee_key 上的访问策略从表 public.emp_dimension 复制到 store.store_sales_fact

=> ALTER ACCESS POLICY ON public.emp_dimension FOR COLUMN employee_key COPY TO TABLE store.store_sales_fact;