# ALTER DEFAULT PRIVILEGES
#### 功能描述
设置应用于将来要创建的对象的权限（不会影响现有对象的权限）。
用户只可以修改由用户本身或者用户本身所属的角色所创建的对象的默认权限，这些权限可以对全局范围设置（即数据库中创建的所有对象），也可以为指定模式下的对象设置。
可使用PG_DEFAULT_ACL系统表查看数据库用户的默认权限的信息。
#### 注意事项
- 目前只支持表（包括视图）、序列、函数和类型（包括域）的权限更改。
- 不支持将外表的VACUUM，DROP，ALTER的权限赋予用户。
 
#### 语法格式
```
ALTER DEFAULT PRIVILEGES
    [ FOR { ROLE | USER } target_role [, ...] ]
    [ IN SCHEMA schema_name [, ...] ]
    abbreviated_grant_or_revoke;
```
abbreviated_grant_or_revoke子句用于指定对哪些对象进行授权或回收权限，可以是以下选项之一：
```
grant_on_tables_clause
grant_on_functions_clause
grant_on_types_clause
grant_on_sequences_clause
revoke_on_tables_clause
revoke_on_functions_clause
revoke_on_types_clause
revoke_on_sequences_clause
```
- grant_on_tables_clause子句用于对表授权。
  ```
  GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | ANALYZE | ANALYSE | VACUUM | ALTER | DROP } 
      [, ...] | ALL [ PRIVILEGES ] }
      ON TABLES 
      TO { [ GROUP ] role_name | PUBLIC } [, ...]
      [ WITH GRANT OPTION ]
  ```
  
- grant_on_functions_clause子句用于对函数授权。
  ```
  GRANT { { EXECUTE | ALTER | DROP } [, ...] | ALL [ PRIVILEGES ] }
      ON FUNCTIONS 
      TO { [ GROUP ] role_name | PUBLIC } [, ...]
      [ WITH GRANT OPTION ]
  ```
  
- grant_on_types_clause子句用于对类型授权。
  ```
  GRANT { USAGE | ALL [ PRIVILEGES ] }
      ON TYPES 
      TO { [ GROUP ] role_name | PUBLIC } [, ...]
      [ WITH GRANT OPTION ]
  ```
  
- grant_on_sequences_clause子句用于对序列授权。
  ```
  GRANT { { USAGE | SELECT | UPDATE }
      [, ...] | ALL [ PRIVILEGES ] }
      ON SEQUENCES 
      TO { [ GROUP ] role_name | PUBLIC } [, ...]
      [ WITH GRANT OPTION ]
  ```
  
- revoke_on_tables_clause子句用于回收表对象的权限。
  ```
  REVOKE [ GRANT OPTION FOR ]
      { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | ANALYZE | ANALYSE | VACUUM | ALTER | DROP } 
      [, ...] | ALL [ PRIVILEGES ] }
      ON TABLES 
      FROM { [ GROUP ] role_name | PUBLIC } [, ...]
      [ CASCADE | RESTRICT | CASCADE CONSTRAINTS ]
  ```
  
- revoke_on_functions_clause子句用于回收函数的权限。
  ```
  REVOKE [ GRANT OPTION FOR ]
      { { EXECUTE | ALTER | DROP } [, ...] | ALL [ PRIVILEGES ] }
      ON FUNCTIONS 
      FROM { [ GROUP ] role_name | PUBLIC } [, ...]
      [ CASCADE | RESTRICT | CASCADE CONSTRAINTS ]
  ```
  
- revoke_on_types_clause子句用于回收类型的权限。
  ```
  REVOKE [ GRANT OPTION FOR ]
      { USAGE | ALL [ PRIVILEGES ] }
      ON TYPES 
      FROM { [ GROUP ] role_name | PUBLIC } [, ...]
      [ CASCADE | RESTRICT | CASCADE CONSTRAINTS ]
  ```
  
- revoke_on_sequences_clause子句用于回收序列的权限。
  ```
  REVOKE [ GRANT OPTION FOR ]
      { { USAGE | SELECT | UPDATE }
      [, ...] | ALL [ PRIVILEGES ] }
      ON SEQUENCES 
      FROM { [ GROUP ] role_name | PUBLIC } [, ...]
      [ CASCADE | RESTRICT | CASCADE CONSTRAINTS ]
  ```
  
 
#### 参数说明
表1ALTER DEFAULT PRIVILEGES参数说明 
| 参数                                           | 描述                                                                                                                                                                                                                                                                                                                                                                                       | 取值范围或示例                                                                                                                                                                                                                                                                                                                                                         |
|:---|:---|:---|
| FOR { ROLE \| USER } target_role \[, ...\] | FOR ROLE/USER 后面跟着的target_role是指将来要创建对象的角色或用户名称，即要访问谁未来创建的对象，就写这个owner对应的角色或用户名称。如果省略FOR ROLE/USER，则缺省值为当前角色/用户。 target_role必须有schema_name的CREATE权限。查看角色/用户是否具有schema的CREATE权限可使用has_schema_privilege函数。 ``` SELECT a.rolname, n.nspname FROM pg_authid as a, pg_namespace as n WHERE has_schema_privilege(a.oid, n.oid, 'CREATE'); ``` | 已有角色或用户名称。 举例，授权用户jim可访问用户lily未来创建对象的权限。 ``` ALTER DEFAULT PRIVILEGES FOR ROLE lily IN SCHEMA lily GRANT SELECT ON tables TO jim; ``` 或者 ``` ALTER DEFAULT PRIVILEGES FOR USER lily IN SCHEMA lily GRANT SELECT ON tables TO jim; ```  |
| schema_name                                | 已有模式名称。 如果指定了模式名，那么之后在这个模式下面创建的所有对象默认的权限都会被修改。如果IN SCHEMA被省略，那么全局权限会被修改。 如果模式名为public，需要指定for user target_role。                                                                                                                                                                             | 已有模式名称。                                                                                                                                                                                                                                                                                                                                                           |
| role_name                                 | 被授予或者取消权限的角色名称。 说明： 如果需删除一个被赋予了默认权限的角色，必须撤销其默认权限的更改或者使用DROP OWNED BY删除该角色的默认权限记录。                                                                                                                                                                                                                                                       | 已有角色名称。                                                                                                                                                                                                                                                                                                                                                          |
   
#### 示例
- **前提条件** ：创建测试模式tpcds、表和用户，为以下示例准备样例数据。
  ```
  CREATE SCHEMA tpcds;
  CREATE TABLE tpcds.teama (a int,b int);
  CREATE TABLE tpcds.teamb (a int,b int);
  DROP USER IF EXISTS test1;
  DROP USER IF EXISTS test2;
  CREATE USER test1 PASSWORD '{Password}';
  CREATE USER test2 PASSWORD '{Password}';
  CREATE USER jack PASSWORD '{Password}';
  ```
  
- 将创建在模式tpcds里的所有表（和视图）的SELECT权限授予每一个用户。
  ```
  ALTER DEFAULT PRIVILEGES IN SCHEMA tpcds GRANT SELECT ON TABLES TO PUBLIC;
  ```
  
- 将tpcds下的所有表的插入权限授予用户jack。
  ```
  ALTER DEFAULT PRIVILEGES IN SCHEMA tpcds GRANT INSERT ON TABLES TO jack;
  ```
  
- 撤销上述权限。
  ```
  ALTER DEFAULT PRIVILEGES IN SCHEMA tpcds REVOKE SELECT ON TABLES FROM PUBLIC; 
  ALTER DEFAULT PRIVILEGES IN SCHEMA tpcds REVOKE INSERT ON TABLES FROM jack;
  ```
  
- 假设有两个用户test1、test2，如果需要test2用户对test1用户未来创建的表都有查询权限，可执行如下操作：
  1. 将test1的schema的权限赋予test2用户。
     ```
     GRANT usage, create ON SCHEMA test1 TO test2;
     ```
     
  
  2. 将test1用户下的表的查询权限赋予test2用户。**注** ，以下的FOR USER也可以改成FOR ROLE，作用效果一致。
     ```
     ALTER DEFAULT PRIVILEGES FOR USER test1 IN SCHEMA test1 GRANT SELECT ON tables TO test2;
     ```
     
  
  3. test1用户创建表。
     ```
     SET ROLE test1 password '{password}';
     CREATE TABLE test3( a int, b int);
     ```
     
  
  4. 使test2用户执行查询。
     ```
     SET ROLE test2 password '{password}';
     SELECT * FROM test1.test3;
      a | b
     ---+---
     (0 rows)
     ```
     
   
 
#### 相关链接
[GRANT](https://support.huaweicloud.com/sqlreference-dws/dws_06_0250.html)，[REVOKE](https://support.huaweicloud.com/sqlreference-dws/dws_06_0253.html)
