9.26. Системные информационные функции и операторы

В Таблице 9.63 перечислен ряд функций, предназначенных для получения информации о текущем сеансе и системе.

В дополнение к перечисленным здесь функциям существуют также функции, связанные с подсистемой статистики, которые тоже предоставляют системную информацию. Подробнее они рассматриваются в Подразделе 27.2.2.

Таблица 9.63. Функции получения информации о сеансе

Функция

Описание

current_catalogname

current_database () → name

Выдаёт имя текущей базы данных. (В стандарте SQL базы данных называются «каталогами», поэтому стандарту соответствует написание current_catalog.)

current_query () → text

Выдаёт текст запроса, выполняемого в данный момент, в том виде, в каком его передал клиент (может состоять из нескольких операторов).

current_rolename

Аналог current_user.

current_schemaname

current_schema () → name

Выдаёт имя первой схемы в пути поиска (или значение NULL, если путь поиска пустой). В эту схему будут добавляться таблицы и другие объекты, при создании которых схема не указывается явно.

current_schemas ( include_implicit boolean ) → name[]

Выдаёт массив имён всех схем, в настоящее время представленных в действующем пути поиска, по порядку их приоритета. (Элементы текущего значения search_path, которым не соответствуют существующие схемы, опускаются). Если логический аргумент равен true, в результат включаются системные схемы, неявно просматриваемые при поиске, например, pg_catalog.

current_username

Выдаёт имя пользователя в текущем контексте выполнения.

inet_client_addr () → inet

Выдаёт IP-адрес текущего клиента либо NULL, если текущее соединение установлено через Unix-сокет.

inet_client_port () → integer

Выдаёт номер TCP-порта текущего клиента либо NULL, если текущее подключение установлено через Unix-сокет.

inet_server_addr () → inet

Выдаёт IP-адрес, через который сервер принял текущее подключение, либо NULL, если текущее подключение установлено через Unix-сокет.

inet_server_port () → integer

Выдаёт номер TCP-порта, через который сервер принял текущее подключение, либо NULL, если текущее подключение установлено через Unix-сокет.

pg_backend_pid () → integer

Выдаёт идентификатор серверного процесса, обслуживающего текущий сеанс.

pg_blocking_pids ( integer ) → integer[]

Выдаёт массив с идентификаторами процессов сеансов, которые блокируют серверный процесс с указанным идентификатором, либо пустой массив, если указанный серверный процесс не найден или не заблокирован.

Один серверный процесс блокирует другой, если он либо удерживает блокировку, конфликтующую с блокировкой, запрашиваемой вторым (жёсткая блокировка), либо ожидает блокировку, которая вызвала бы конфликт с запросом блокировки заблокированного процесса и находится перед ней в очереди ожидания (мягкая блокировка). При распараллеливании запросов эта функция всегда выдаёт видимые клиентом идентификаторы процессов (то есть, результаты pg_backend_pid), даже если фактическая блокировка удерживается или ожидается дочерним рабочим процессом. Вследствие этого в результатах могут оказаться дублирующиеся PID. Также заметьте, что когда конфликтующую блокировку удерживает подготовленная транзакция, в выводе этой функции она будет представлена нулевым ID процесса.

Частые вызовы этой функции могут отразиться на производительности базы данных, так как ей нужен монопольный доступ к общему состоянию менеджера блокировок, пусть и на короткое время.

pg_conf_load_time () → timestamp with time zone

Выдаёт время, когда в последний раз сервер загружал файлы конфигурации. (Если текущий сеанс начался раньше, она возвращает время, когда эти файлы были перезагружены для данного сеанса, так что в разных сеансах это значение может немного различаться. В противном случае это будет время, когда файлы конфигурации считал главный процесс.)

pg_current_logfile ( [text] ) → text

Выдаёт путь к файлу журнала, в настоящее время используемому сборщиком сообщений. Этот путь состоит из пути каталога log_directory и имени конкретного файла. Если сборщик сообщений отключён, выдаётся значение NULL. Если ведутся несколько журналов в разных форматах, при вызове функции pg_current_logfile без аргументов возвращается путь первого существующего файла следующего формата (в порядке приоритета): stderr, csvlog. Если файл журнала в этих форматах отсутствует, выдаётся NULL. Чтобы запросить информацию о файле в определённом формате, передайте либо csvlog, либо stderr в качестве значения необязательного параметра типа text. Если запрошенный формат не включён в log_destination, результатом будет NULL. Результат функции отражает содержимое файла current_logfiles.

pg_my_temp_schema () → oid

Выдаёт OID временной схемы текущего сеанса или 0, если такой схемы нет (в рамках сеанса не создавались временные таблицы).

pg_is_other_temp_schema ( oid ) → boolean

Выдаёт true, если заданный OID относится к временной схеме другого сеанса. (Это может быть полезно, например для исключения временных таблиц других сеансов из общего списка при просмотре таблиц базы данных.)

pg_jit_available () → boolean

Выдаёт true, если в данном сеансе доступна JIT-компиляция (см. Главу 31) и параметр конфигурации jit включён.

pg_listening_channels () → setof text

Выдаёт список имён каналов асинхронных уведомлений, по которым текущий сеанс принимает сигналы.

pg_notification_queue_usage () → double precision

Выдаёт долю (0–1) максимального размера очереди асинхронных уведомлений, в настоящее время занятую уведомлениями, ожидающими обработки. За дополнительными сведениями обратитесь к LISTEN и NOTIFY.

pg_postmaster_start_time () → timestamp with time zone

Выдаёт время, когда был запущен сервер.

pg_safe_snapshot_blocking_pids ( integer ) → integer[]

Выдаёт массив с идентификаторами процессов сеансов, которые блокируют серверный процесс с указанным идентификатором, не давая ему получить безопасный снимок, либо выдаёт пустой массив, если такой серверный процесс не найден или он не заблокирован.

Сеанс, выполняющий транзакцию уровня SERIALIZABLE, блокирует транзакцию SERIALIZABLE READ ONLY DEFERRABLE, не давая ей получить снимок, пока она не определит, что можно безопасно избежать установления предикатных блокировок. За дополнительными сведениями о сериализуемых и откладываемых транзакциях обратитесь к Подразделу 13.2.3.

Частые вызовы этой функции могут отразиться на производительности сервера, так как ей нужен доступ к общему состоянию менеджера предикатных блокировок, пусть и на короткое время.

pg_trigger_depth () → integer

Выдаёт текущий уровень вложенности в триггерах Postgres Pro (0, если эта функция вызывается не из тела триггера, непосредственно или косвенно).

session_username

Выдаёт имя пользователя сеанса.

username

Аналог current_user.

version () → text

Выдаёт текстовую строку, описывающую версию сервера PostgreSQL. Эту информацию также можно получить из переменной server_version или, в более машинно-ориентированном формате, из переменной server_version_num. При разработке программ следует использовать функцию server_version_num (появившуюся в версии 8.2) или PQserverVersion, а не разбирать текстовую версию.

pgpro_version () → text

Выдаёт текстовую строку, описывающую версию сервера Postgres Pro.

pgpro_edition () → text

Выдаёт текстовую строку, описывающую редакцию Postgres Pro, например standard или enterprise.

pgpro_build () → text

Выдаёт идентификатор состояния исходного кода, из которого скомпилирован Postgres Pro.


Примечание

Функции current_catalog, current_role, current_schema, current_user, session_user и user имеют особый синтаксический статус в SQL: они должны вызываться без скобок после имени. Postgres Pro позволяет добавить скобки в вызове current_schema, но не других функций.

Функция session_user обычно возвращает имя пользователя, установившего текущее соединение с базой данных, но суперпользователи могут изменить это имя, выполнив команду SET SESSION AUTHORIZATION. Функция current_user возвращает идентификатор пользователя, по которому будут проверяться его права. Обычно это тот же пользователь, что и пользователь сеанса, но его можно сменить с помощью SET ROLE. Этот идентификатор также меняется при выполнении функций с атрибутом SECURITY DEFINER. На языке Unix пользователь сеанса называется «реальным», а текущий — «эффективным». Имена current_role и user являются синонимами current_user. (В стандарте SQL current_role и current_user имеют разное значение, но в Postgres Pro они не различаются, так как пользователи и роли объединены в единую сущность.)

В Таблице 9.64 показаны функции, позволяющие программно проверить права доступа к объектам. (Подробнее о правах рассказывается в Разделе 5.7.) Этим функциям в качестве идентификатора пользователя, для которого запрашиваются права, можно передать его имя или OID (pg_authid.oid), а также можно передать public (это будет указывать на псевдороль PUBLIC). Кроме того, аргумент user можно полностью опустить, тогда будет подразумеваться current_user. Объект, права для доступа к которому запрашиваются, также можно задать по имени или по OID. Когда указывается имя объекта, его можно дополнить именем схемы, если это уместно. Запрашиваемое право записывается текстовой строкой, которая должна задавать одно из прав доступа, соответствующих типу объекта (например, SELECT). Дополнительно к названию права можно добавить WITH GRANT OPTION и проверить, разрешено ли пользователю передавать это право другим. Кроме того, в одном параметре можно перечислить несколько прав через запятую, и тогда функция возвратит true, если пользователь имеет какие-либо из них. (Регистр в названии прав не имеет значения, а между ними (но не внутри) разрешены пробельные символы.) Пара примеров:

SELECT has_table_privilege('myschema.mytable', 'select');
SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION');

Таблица 9.64. Функции для проверки прав доступа

Функция

Описание

has_any_column_privilege ( [user name или oid, ] table text или oid, privilege text ) → boolean

Имеет ли пользователь указанное право для какого-либо столбца таблицы? Ответ положительный, когда он имеет это право для всей таблицы или ему дано соответствующее право на уровне столбцов хотя бы для одного столбца. Возможные права: SELECT, INSERT, UPDATE и REFERENCES.

has_column_privilege ( [user name или oid, ] table text или oid, column text или smallint, privilege text ) → boolean

Имеет ли пользователь указанное право для заданного столбца таблицы? Ответ положительный, когда он имеет это право для всей таблицы или ему дано соответствующее право на уровне столбца. Столбец можно задать по имени или номеру атрибута (pg_attribute.attnum). Возможные права: SELECT, INSERT, UPDATE и REFERENCES.

has_database_privilege ( [user name или oid, ] database text или oid, privilege text ) → boolean

Имеет ли пользователь указанное право в базе данных? Возможные права: CREATE, CONNECT, TEMPORARY и TEMP (синоним TEMPORARY).

has_foreign_data_wrapper_privilege ( [user name или oid, ] fdw text или oid, privilege text ) → boolean

Имеет ли пользователь право для обёртки сторонних данных? На данный момент возможно только одно право: USAGE.

has_function_privilege ( [user name или oid, ] function text или oid, privilege text ) → boolean

Имеет ли пользователь право для функции? Возможно единственное право: EXECUTE.

При указании функции по имени, а не по OID, допускаются те же входные значения, что и для типа regprocedure (см. Раздел 8.19). Например:

SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');

has_language_privilege ( [user name или oid, ] language text или oid, privilege text ) → boolean

Имеет ли пользователь право для языка? Возможно единственное право: USAGE.

has_schema_privilege ( [user name или oid, ] schema text или oid, privilege text ) → boolean

Имеет ли пользователь право для схемы? Возможные права: CREATE и USAGE.

has_sequence_privilege ( [user name или oid, ] sequence text или oid, privilege text ) → boolean

Имеет ли пользователь право для последовательности? Возможные права: USAGE, SELECT и UPDATE.

has_server_privilege ( [user name или oid, ] server text или oid, privilege text ) → boolean

Имеет ли пользователь право для стороннего сервера? На данный момент возможно только одно право: USAGE.

has_table_privilege ( [user name или oid, ] table text или oid, privilege text ) → boolean

Имеет ли пользователь право для таблицы? Возможные права: SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES и TRIGGER.

has_tablespace_privilege ( [user name или oid, ] tablespace text или oid, privilege text ) → boolean

Имеет ли пользователь право для табличного пространства? Возможно единственное право: CREATE.

has_type_privilege ( [user name или oid, ] type text или oid, privilege text ) → boolean

Имеет ли пользователь право для типа данных? Возможно единственное право: USAGE. При указании типа по имени, а не по OID, допускаются те же входные значения, что и для типа данных regtype (см. Раздел 8.19).

pg_has_role ( [user name или oid, ] role text или oid, privilege text ) → boolean

Имеет ли пользователь право для роли? Возможные права: MEMBER и USAGE. Под MEMBER подразумевается непосредственное или косвенное членство в роли (то есть право выполнить команду SET ROLE), тогда как USAGE означает, что пользователь получает права этой роли автоматически, не выполняя SET ROLE. К любому из этих типов прав можно добавить WITH ADMIN OPTION или WITH GRANT OPTION, чтобы проверить наличие права ADMIN (все четыре варианта написания проверяют одно и то же). Эта функция не поддерживает особый случай установки значения public для user, так как псевдороль PUBLIC не может быть членом обычных ролей.

row_security_active ( table text или oid ) → boolean

Действует ли защита на уровне строк для заданной таблицы в контексте текущего пользователя в текущем окружении?


В Таблице 9.65 показаны операторы, предназначенные для работы с типом aclitem, который представляет в системном каталоге права доступа. О содержании значений этого типа рассказывается в Разделе 5.7.

Таблица 9.65. Операторы для типа aclitem

Оператор

Описание

Пример(ы)

aclitem = aclitemboolean

Значения aclitem равны? (Заметьте, что для типа aclitem не определён обычный набор операторов сравнения, поддерживается только проверка равенства. Массивы aclitem, в свою очередь, также могут сравниваться только на равенство.)

'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitemf

aclitem[] @> aclitemboolean

Содержит ли массив заданное право? (Ответ положительный, если в массиве есть запись, соответствующая правообладателю и праводателю из aclitem и содержащая как минимум указанный набор прав.)

'{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*/hobbes'::aclitemt

aclitem[] ~ aclitemboolean

Это устаревший синоним для @>.

'{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] ~ 'calvin=r*/hobbes'::aclitemt


В Таблице 9.66 приведены дополнительные функции, предназначенные для работы с типом aclitem.

Таблица 9.66. Функции для типа aclitem

Функция

Описание

acldefault ( type "char", ownerId oid ) → aclitem[]

Выдаёт массив с элементами aclitem, содержащий действующий по умолчанию набор прав доступа для объектов типа type, принадлежащих роли ownerId. Результат показывает, какие права доступа подразумеваются, когда список ACL определённого объекта пуст. (Права доступа, действующие по умолчанию, описываются в Разделе 5.7.) Параметр type может принимать одно из следующих значений: 'c' —столбец (COLUMN), 'r' — таблица или подобный таблице объект (TABLE), 's' — последовательность (SEQUENCE), 'd' — база данных (DATABASE), 'f' — функция (FUNCTION) или процедура (PROCEDURE), 'l' — язык (LANGUAGE), 'L' — большой объект (LARGE OBJECT), 'n' — схема (SCHEMA), 't' — табличное пространство (TABLESPACE), 'F' — обёртка сторонних данных (FOREIGN DATA WRAPPER), 'S' — сторонний сервер (FOREIGN SERVER) и 'T' — тип (TYPE) или домен (DOMAIN).

aclexplode ( aclitem[] ) → setof record ( grantor oid, grantee oid, privilege_type text, is_grantable boolean )

Возвращает массив aclitem в виде набора табличных строк. Если праводателем является псевдороль PUBLIC, она представляется нулём в столбце grantee. Назначенные права представляются ключевыми словами SELECT, INSERT и т. д. Заметьте, что каждое право выводится в отдельной строке, так что в столбце privilege_type содержится только одно ключевое слово.

makeaclitem ( grantee oid, grantor oid, privileges text, is_grantable boolean ) → aclitem

Конструирует значение aclitem с заданными свойствами.


В Таблице 9.67 показаны функции, определяющие видимость объекта с текущим путём поиска схем. К примеру, таблица считается видимой, если содержащая её схема включена в путь поиска и нет другой таблицы с тем же именем, которая была бы найдена в этом пути раньше. Другими словами, к этой таблице можно будет обратиться просто по её имени, без явного указания схемы. Просмотреть список всех видимых таблиц можно так:

SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);

Объект, представляющий функцию и оператор, считаются видимым в пути поиска, если при просмотре пути не находится предшествующий ему другой объект с тем же именем и типами аргументов. Для семейств и классов операторов помимо имени объекта во внимание принимается также связанный метод доступа к индексу.

Таблица 9.67. Функции для определения видимости

Функция

Описание

pg_collation_is_visible ( collation oid ) → boolean

Видимо ли правило сортировки в пути поиска?

pg_conversion_is_visible ( conversion oid ) → boolean

Видимо ли преобразование в пути поиска?

pg_function_is_visible ( function oid ) → boolean

Видима ли функция в пути поиска? (Также работает для процедур и агрегатных функций.)

pg_opclass_is_visible ( opclass oid ) → boolean

Виден ли класс операторов в пути поиска?

pg_operator_is_visible ( operator oid ) → boolean

Видим ли оператор в пути поиска?

pg_opfamily_is_visible ( opclass oid ) → boolean

Видимо ли семейство операторов в пути поиска?

pg_statistics_obj_is_visible ( stat oid ) → boolean

Видим ли объект статистики в пути поиска?

pg_table_is_visible ( table oid ) → boolean

Видима ли таблица в пути поиска? (Эта проверка работает со всеми типами отношений, включая представления, матпредставления, индексы, последовательности и сторонние таблицы.)

pg_ts_config_is_visible ( config oid ) → boolean

Видима ли конфигурация текстового поиска?

pg_ts_dict_is_visible ( dict oid ) → boolean

Видим ли словарь текстового поиска?

pg_ts_parser_is_visible ( parser oid ) → boolean

Видим ли анализатор текстового поиска?

pg_ts_template_is_visible ( template oid ) → boolean

Видим ли шаблон текстового поиска?

pg_type_is_visible ( type oid ) → boolean

Видим ли тип (или домен) в пути поиска?


Всем этим функциям должен передаваться OID проверяемого объекта. Если вы хотите проверить объект по имени, удобнее использовать типы-псевдонимы OID (regclass, regtype, regprocedure, regoperator, regconfig или regdictionary), например:

SELECT pg_type_is_visible('myschema.widget'::regtype);

Заметьте, что проверять таким способом имена без указания схемы не имеет большого смысла — если имя удастся распознать, значит и объект будет видимым.

В Таблице 9.68 перечислены функции, извлекающие информацию из системных каталогов.

Таблица 9.68. Функции для обращения к системным каталогам

Функция

Описание

format_type ( type oid, typemod integer ) → text

Выдаёт в формате SQL имя типа данных, определяемого по OID и, возможно, модификатору типа. Если модификатор неизвестен, вместо него можно передать NULL.

pg_get_constraintdef ( constraint oid [, pretty boolean] ) → text

Восстанавливает команду, создающую ограничение. (Текст команды не является изначальны