54.66. Системные представления

В дополнение к системным каталогам, в Postgres Pro есть набор встроенных представлений. Некоторые системные представления содержат в себе некоторые популярные запросы к системным каталогам, а другие дают доступ к внутреннему состоянию сервера.

Информационная схема (см. Главу 39) содержит другой набор представлений, пересекающихся по функциональности с системными представлениям. Так как информационная схема соответствует стандарту SQL, тогда как описанные здесь представления свойственны только для Postgres Pro, обычно лучше использовать информационную схему, если через неё можно получить всю требуемую информацию.

В Таблице 54.67 перечислены описываемые здесь системные представления. Подробное описание каждого представления следует далее. Есть также дополнительные представления, дающие доступ к результатам работы сборщика статистики; они перечисляются в Таблице 27.2.

Кроме явно отмеченных исключений, все описанные здесь представления доступны только для чтения.

Таблица 54.67. Системные представления

Имя представленияПредназначение
pg_available_extensionsдоступные расширения
pg_available_extension_versionsдоступные версии расширений
pg_backend_memory_contextsконтекст памяти обслуживающего процесса
pg_configпараметры конфигурации времени компиляции
pg_cursorsоткрытые курсоры
pg_file_settingsсводка содержимого файла конфигурации
pg_groupгруппы пользователей баз данных
pg_hba_file_rulesсводка содержимого файла конфигурации аутентификации клиентов
pg_indexesиндексы
pg_locksблокировки, установленные или ожидаемые в данный момент
pg_matviewsматериализованные представления
pg_policiespolicies
pg_prepared_statementsподготовленные операторы
pg_autoprepared_statementsавтоподготовленные операторы
pg_prepared_xactsподготовленные транзакции
pg_publication_tablesпубликации и связанные с ними таблицы
pg_replication_origin_statusинформация об источниках репликации, включая данные прогресса репликации
pg_replication_slotsинформация о слотах репликации
pg_rolesроли баз данных
pg_rulesправила
pg_seclabelsметки безопасности
pg_sequencesпоследовательности
pg_settingsзначения параметров
pg_shadowпользователи базы данных
pg_shmem_allocationsблоки, выделенные в общей памяти
pg_statsстатистика планировщика
pg_stats_extрасширенная статистика планировщика
pg_stats_ext_exprsрасширенная статистика планировщика по выражениям
pg_tablesтаблицы
pg_timezone_abbrevsаббревиатуры часовых поясов
pg_timezone_namesимена часовых поясов
pg_userпользователи базы данных
pg_user_mappingsсопоставления пользователей
pg_viewsпредставления

47.6. Examples

This section contains a very simple example of SPI usage. The C function execq takes an SQL command as its first argument and a row count as its second, executes the command using SPI_exec and returns the number of rows that were processed by the command. You can find more complex examples for SPI in the source tree in src/test/regress/regress.c and in the spi module.

#include "postgres.h"

#include "executor/spi.h"
#include "utils/builtins.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(execq);

Datum
execq(PG_FUNCTION_ARGS)
{
    char *command;
    int cnt;
    int ret;
    uint64 proc;

    /* Convert given text object to a C string */
    command = text_to_cstring(PG_GETARG_TEXT_PP(0));
    cnt = PG_GETARG_INT32(1);

    SPI_connect();

    ret = SPI_exec(command, cnt);

    proc = SPI_processed;

    /*
     * If some rows were fetched, print them via elog(INFO).
     */
    if (ret > 0 && SPI_tuptable != NULL)
    {
        TupleDesc tupdesc = SPI_tuptable->tupdesc;
        SPITupleTable *tuptable = SPI_tuptable;
        char buf[8192];
        uint64 j;

        for (j = 0; j < proc; j++)
        {
            HeapTuple tuple = tuptable->vals[j];
            int i;

            for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++)
                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %s%s",
                        SPI_getvalue(tuple, tupdesc, i),
                        (i == tupdesc->natts) ? " " : " |");
            elog(INFO, "EXECQ: %s", buf);
        }
    }

    SPI_finish();
    pfree(command);

    PG_RETURN_INT64(proc);
}

This is how you declare the function after having compiled it into a shared library (details are in Section 38.10.5.):

CREATE FUNCTION execq(text, integer) RETURNS int8
    AS 'filename'
    LANGUAGE C STRICT;

Here is a sample session:

=> SELECT execq('CREATE TABLE a (x integer)', 0);
 execq
-------
     0
(1 row)

=> INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)', 0));
INSERT 0 1
=> SELECT execq('SELECT * FROM a', 0);
INFO:  EXECQ:  0    -- inserted by execq
INFO:  EXECQ:  1    -- returned by execq and inserted by upper INSERT

 execq
-------
     2
(1 row)

=> SELECT execq('INSERT INTO a SELECT x + 2 FROM a RETURNING *', 1);
INFO:  EXECQ:  2    -- 0 + 2, then execution was stopped by count
 execq
-------
     1
(1 row)

=> SELECT execq('SELECT * FROM a', 10);
INFO:  EXECQ:  0
INFO:  EXECQ:  1
INFO:  EXECQ:  2

 execq
-------
     3              -- 10 is the max value only, 3 is the real number of rows
(1 row)

=> SELECT execq('INSERT INTO a SELECT x + 10 FROM a', 1);
 execq
-------
     3              -- all rows processed; count does not stop it, because nothing is returned
(1 row)

=> SELECT * FROM a;
 x
----
  0
  1
  2
 10
 11
 12
(6 rows)

=> DELETE FROM a;
DELETE 6
=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
INSERT 0 1
=> SELECT * FROM a;
 x
---
 1                  -- 0 (no rows in a) + 1
(1 row)

=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
INFO:  EXECQ:  1
INSERT 0 1
=> SELECT * FROM a;
 x
---
 1
 2                  -- 1 (there was one row in a) + 1
(2 rows)

-- This demonstrates the data changes visibility rule.
-- execq is called twice and sees different numbers of rows each time:

=> INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
INFO:  EXECQ:  1    -- results from first execq
INFO:  EXECQ:  2
INFO:  EXECQ:  1    -- results from second execq
INFO:  EXECQ:  2
INFO:  EXECQ:  2
INSERT 0 2
=> SELECT * FROM a;
 x
---
 1
 2
 2                  -- 2 rows * 1 (x in first row)
 6                  -- 3 rows (2 + 1 just inserted) * 2 (x in second row)
(4 rows)