表9-40显示了几个抽取会话及系统信息的函数。
表9-40. 会话信息函数
名字 | 返回类型 | 描述 |
---|---|---|
current_database () | name | 当前数据库的名字 |
current_schema () | name | 当前模式的名字 |
current_schemas (boolean) | name[] | 搜索路径中的模式名字 |
current_user | name | 当前执行环境下的用户名 |
inet_client_addr () | inet | 连接的远端地址 |
inet_client_port () | int | 连接的远端端口 |
inet_server_addr () | inet | 连接的本地地址 |
inet_server_port () | int | 连接的本地端口 |
pg_my_temp_schema () | oid | 会话的临时模式的 OID ,不存在则为 0 |
pg_is_other_temp_schema (oid) | boolean | 是否为另一个会话的临时模式? |
pg_postmaster_start_time () | timestamp with time zone | 服务器启动时间 |
session_user | name | 会话用户名 |
user | name | 等价于 current_user |
version () | text | PostgreSQL 版本信息 |
session_user
通常是连接当前数据库的初始用户,不过超级用户可以用 SET SESSION AUTHORIZATION 修改这个设置。current_user
是用于权限检查的用户标识。通常,它总是等于会话用户,但是可以通过 SET ROLE 改变它。在函数执行的过程中随着属性 SECURITY DEFINER 的改变,其值也会改变。用 Unix 术语来说,会话用户是"真实用户",而当前用户是"有效用户"。
【注意】
current_user
,session_user
,user
在 SQL 里有特殊的语法:调用时结尾不能跟园括号。
current_schema
返回在搜索路径前端的模式名字(如果搜索路径为空则返回 NULL)。如果创建表或者其它命名对象时没有声明目标模式,那么它将是用于这些对象的模式。current_schemas(boolean)
返回一个搜索路径中所有模式名字的数组。布尔选项决定像 pg_catalog 这样隐含包含的系统模式是否包含在返回的搜索路径中。
【注意】搜索路径可以通过运行时设置更改。命令是:
SET search_path TO schema [, schema, ...]
inet_client_addr
返回当前客户端的IP地址,而 inet_client_port
则返回当前客户端的端口号。inet_server_addr
返回服务器接收当前连接用的 IP 地址,而 inet_server_port
返回接收当前连接的端口号。如果是通过 Unix-domain socket 连接的,那么所有这些函数都返回 NULL 。
pg_my_temp_schema
返回当前会话的临时模式 OID ,如果不存在的话则返回 0(因为没有创建任何临时表)。pg_is_other_temp_schema
返回给定的 OID 是否为其它会话的临时模式 OID ,这个函数是有实用价值的,比如,在显示一个目录的时候排除掉其它会话的临时表。
pg_postmaster_start_time
返回服务器启动时的 timestamp with time zone 。
version
返回一个描述 PostgreSQL 服务器版本信息的字符串。
表9-41列出那些允许用户在程序里查询对象访问权限的函数。参阅节5.6获取更多有关权限的信息。
表9-41. 访问权限查询函数
名字 | 返回类型 | 描述 |
---|---|---|
has_database_privilege (user, database, privilege) | boolean | 指定用户是否有访问数据库的权限 |
has_database_privilege (database, privilege) | boolean | 当前用户是否有访问数据库的权限 |
has_function_privilege (user, function, privilege) | boolean | 指定用户是否有访问函数的权限 |
has_function_privilege (function, privilege) | boolean | 指定用户是否有访问函数的权限 |
has_language_privilege (user, language, privilege) | boolean | 指定用户是否有访问语言的权限 |
has_language_privilege (language, privilege) | boolean | 指定用户是否有访问语言的权限 |
has_schema_privilege (user, schema, privilege) | boolean | 指定用户是否有访问模式的权限 |
has_schema_privilege (schema, privilege) | boolean | 指定用户是否有访问模式的权限 |
has_table_privilege (user, table, privilege) | boolean | 指定用户是否有访问表的权限 |
has_table_privilege (table, privilege) | boolean | 指定用户是否有访问表的权限 |
has_tablespace_privilege (user, tablespace, privilege) | boolean | 指定用户是否有访问表空间的权限 |
has_tablespace_privilege (tablespace, privilege) | boolean | 指定用户是否有访问表空间的权限 |
pg_has_role (user, role, privilege) | boolean | 指定用户是否有访问角色的权限 |
pg_has_role (role, privilege) | boolean | 指定用户是否有访问角色的权限 |
has_database_privilege
检查一个用户是否能以特定方式访问一个数据库。它可能的参数类似 has_table_privilege
。权限类型必须是 CREATE, CONNECT, TEMPORARY, TEMP(等价于 TEMPORARY)之一。
has_function_privilege
检查一个用户是否能以特定方式访问一个函数。它可能的参数类似 has_table_privilege
。我们声明一个函数用的是文本字符串而不是 OID ,允许的输入和 regprocedure 数据类型一样(参阅节8.12)。权限类型必须是 EXECUTE 。一个例子如下:
SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
has_language_privilege
检查一个用户是否能以特定方式访问一个过程语言。它可能的参数类似 has_table_privilege
。权限类型必须是 USAGE 。
has_schema_privilege
检查一个用户是否能以特定方式访问一个模式。它可能的参数类似 has_table_privilege
。权限类型必须是 CREATE 或 USAGE 。
has_table_privilege
检查一个用户是否能以特定方式访问一个表。用户可以通过名字或者 OID(pg_authid.oid)来声明,如果省略该参数,则使用 current_user
。该表可以通过名字或者 OID 声明。因此,实际上有六种 has_table_privilege
变体,我们可以通过它们的参数数目和类型来区分它们。如果用名字声明,那么在必要时可以用模式进行修饰。所希望的权限类型是用一个文本字符串来声明的,必须是 SELECT, INSERT, UPDATE, DELETE, REFERENCES, TRIGGER 之一。当然,字符串的大小写没什么关系。例如:
SELECT has_table_privilege('myschema.mytable', 'select');
has_tablespace_privilege
检查一个用户是否能以特定方式访问一个表空间。它可能的参数类似 has_table_privilege
。权限类型必须是 CREATE 。
pg_has_role
检查一个用户是否能以特定方式访问一个角色。它可能的参数类似 has_table_privilege
。权限类型必须是 MEMBER 或 USAGE 。MEMBER 表示是角色中的直接或间接成员关系(也就是 SET ROLE 的权限),而 USAGE 表示角色的权限是否无需 SET ROLE 即可立即生效。
要评估一个用户是否在权限上持有赋权选项,给权限键字附加 WITH GRANT OPTION 即可,比如:'UPDATE WITH GRANT OPTION' 。
表9-42显示了那些判断一个对象是否在当前模式搜索路径中可见的函数。如果一个表所在的模式在搜索路径中,并且没有同名的表出现在搜索路径的更靠前的地方,那么就说这个表是可见的。它等效于表可以不带明确模式修饰进行引用。比如,要列出所有可见表的名字:
SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
表9-42. 模式可见性查询函数
名字 | 返回类型 | 描述 |
---|---|---|
pg_conversion_is_visible (conversion_oid) | boolean | 该转换是否在搜索路径中可见 |
pg_function_is_visible (function_oid) | boolean | 该函数是否在搜索路径中可见 |
pg_operator_is_visible (operator_oid) | boolean | 该操作符是否在搜索路径中可见 |
pg_opclass_is_visible (opclass_oid) | boolean | 该操作符类是否在搜索路径中可见 |
pg_table_is_visible (table_oid) | boolean | 该表是否在搜索路径中可见 |
pg_type_is_visible (type_oid) | boolean | 该类型(域)是否在搜索路径中可见 |
pg_table_is_visible
还可用于视图、索引、序列。pg_type_is_visible
还可用于域。对于函数和操作符,如果在搜索路径中没有名字相同并且参数的数据类型也相同的对象出现在路径中更靠前的位置,那么该对象就是可见的。对于操作符类,则要同时考虑名字和相关的索引访问方法。
所有这些函数都需要使用 OID 来标识要被检查的对象。如果你想通过名字测试对象,那么使用 OID 别名类型(regclass, regtype, regprocedure, regoperator)将会很方便。例如:
SELECT pg_type_is_visible('myschema.widget'::regtype);
请注意用这种方法测试一个未经修饰的名字没什么意义,因为如果一个名字可以被识别,那它首先必须是可见的。
表9-43列出了从系统表中抽取信息的函数。
表9-43. 系统表信息函数
名字 | 返回类型 | 描述 |
---|---|---|
format_type (type_oid, typemod) | text | 获取一个数据类型的 SQL 名称 |
pg_get_constraintdef (constraint_oid) | text | 获取一个约束的定义 |
pg_get_constraintdef (constraint_oid, pretty_bool) | text | 获取一个约束的定义 |
pg_get_expr (expr_text, relation_oid) | text | 反编译一个表达式的内部形式,假设其中的任何 Var 都引用第二个参数指出的关系 |
pg_get_expr (expr_text, relation_oid, pretty_bool) | text | 反编译一个表达式的内部形式,假设其中的任何 Var 都引用第二个参数指出的关系 |
pg_get_indexdef (index_oid) | text | 为索引获取 CREATE INDEX 命令 |
pg_get_indexdef (index_oid, column_no, pretty_bool) | text | 为索引获取 CREATE INDEX 命令,如果 column_no 不为零,则只获取一个索引字段的定义。 |
pg_get_ruledef (rule_oid) | text | 为规则获取 CREATE RULE 命令 |
pg_get_ruledef (rule_oid, pretty_bool) | text | 为规则获取 CREATE RULE 命令 |
pg_get_serial_sequence (table_name, column_name) | text | 获取一个 serial 或 bigserial 字段使用的序列名字 |
pg_get_triggerdef (trigger_oid) | text | 为触发器获取 CREATE [ CONSTRAINT ] TRIGGER 命令 |
pg_get_userbyid (roleid) | name | 获取给定 ID 的角色名 |
pg_get_viewdef (view_name) | text | 为视图获取底层的 SELECT 命令(已废弃) |
pg_get_viewdef (view_name, pretty_bool) | text | 为视图获取底层的 SELECT 命令(已废弃) |
pg_get_viewdef (view_oid) | text | 为视图获取底层的 SELECT 命令 |
pg_get_viewdef (view_oid, pretty_bool) | text | 为视图获取底层的 SELECT 命令 |
pg_tablespace_databases (tablespace_oid) | setof oid | 获取在指定的表空间有元素的数据库 OID 集合 |
format_type
通过某个数据类型的类型 OID 以及可能的类型修饰词返回其 SQL 名称。如果不知道具体的修饰词,那么在类型修饰词的位置传入 NULL 。
pg_get_constraintdef
, pg_get_indexdef
, pg_get_ruledef
, pg_get_triggerdef
分别从一个视图、规则、索引、触发器、约束上重新构造创建它们的命令(反编译的重新构造,而不是该命令的原文)。pg_get_expr
反编译一个独立表达式的内部形式,比如一个字段的缺省值。在检查系统表的内容的时候很有用。pg_get_viewdef
重新构造出定义视图的 SELECT 查询。这些函数大多数都有两个变种,其中一个是"适合打印"的结果。这种格式更容易读,但是缺省的格式更有可能被将来的 PostgreSQL 版本用同样的方法解释;如果是用于转储,那么尽可能避免使用"适合打印"的格式。给 pretty_bool 参数传递 false 生成的结果和那个没有这个参数的变种生成的结果是完全一样。
pg_get_serial_sequence
抓取与一个字段相关的序列名字,如果没有任何序列与给定的字段相关则返回 NULL 。这个名字经过了合适的格式化,可以传递给序列函数(参阅节9.12)。这种相关性可以通过 ALTER SEQUENCE OWNED BY 修改或删除。其实将这个函数命名为 pg_get_owned_sequence
或许更为妥当,因为这个名字反映了它通常用于 serial 或 bigserial 字段的事实。
pg_get_userbyid
通过角色的 OID 抽取对应的用户名。
pg_tablespace_databases
允许检查一个表空间的状况,它返回在该表空间中保存了对象的数据库 OID 集合。如果这个函数返回数据行,那么该表空间就是非空的,因此不能删除。要显示该表空间中的特定对象,你需要把 pg_tablespace_databases
返回的数据库标识与 pg_class 表连接进行查询。
表9-44显示的函数将原来用 COMMENT 命令存储的评注抽取出来。如果没有找到,则返回 NULL 。
表9-44. 注释信息函数
名字 | 返回类型 | 描述 |
---|---|---|
col_description (table_oid, column_number) | text | 获取一个表字段的评注 |
obj_description (object_oid, catalog_name) | text | 获取一个数据库对象的评注 |
obj_description (object_oid) | text | 获取一个数据库对象的评注(已废弃) |
shobj_description (object_oid, catalog_name) | text | 获取一个共享数据库对象的评注 |
col_description
返回一个表中字段的评注,它是通过表 OID 和字段号来声明的。obj_description
不能用于表字段,因为字段没有自己的 OID 。
带有两个参数的 obj_description
返回一个数据库对象的评注,该对象是通过其 OID 和其所属的系统表名字声明的。比如,obj_description(123456,'pg_class') 将返回 OID 为 12345 的表的评注。只带一个参数的 obj_description
只要求对象 OID ,现在已经废弃了,因为我们不再保证 OID 在不同的系统表之间是唯一的,因此可能会返回错误的评注。
shobj_description
和 obj_description
差不多,不同之处仅在于前者用于共享对象。一些系统表是通用于集群中所有数据库的全局表,因此这些表的评注也是全局存储的。