F.59. pg_variables#

F.59. pg_variables

F.59. pg_variables #

F.59.1. О pg_variables #

Версия: 1.2.5

GitHub

Этот модуль распространяется под лицензией PostgreSQL.

F.59.2. Введение #

Модуль pg_variables предоставляет функции для работы с переменными различных типов. Созданные переменные существуют только в текущей пользовательской сессии. По умолчанию, созданные переменные не являются транзакционными (т.е. они не затрагиваются операторами BEGIN, COMMIT или ROLLBACK). Однако это можно настроить с помощью аргумента is_transactional функции pgv_set():

SELECT pgv_set('vars', 'int1', 101);
BEGIN;
SELECT pgv_set('vars', 'int2', 102);
ROLLBACK;

SELECT * FROM pgv_list() order by package, name;
 package | name | is_transactional
---------+------+------------------
 vars    | int1 | f
 vars    | int2 | f

Но если переменная создана с флагом is_transactional:

BEGIN;
SELECT pgv_set('vars', 'trans_int', 101, true);
SAVEPOINT sp1;
SELECT pgv_set('vars', 'trans_int', 102, true);
ROLLBACK TO sp1;
COMMIT;
SELECT pgv_get('vars', 'trans_int', NULL::int);
 pgv_get
---------
     101

Вы можете агрегировать переменные в пакеты. Это делается для того, чтобы иметь переменные с разными именами или быстро удалить весь пакет переменных. Если пакет становится пустым, он автоматически удаляется.

F.59.3. Установка #

Типичная установка:

CREATE EXTENSION pg_variables;

F.59.4. Функции модуля #

Функции, предоставляемые модулем pg_variables, показаны в таблицах ниже.

Чтобы использовать функцию pgv_get(), необходимый пакет и переменная должны существовать. Необходимо установить переменную с помощью функции pgv_set(), чтобы использовать функцию pgv_get().

Если пакет не существует, вы получите следующую ошибку:

SELECT pgv_get('vars', 'int1', NULL::int);
ERROR:  unrecognized package "vars"

Если переменная не существует, вы получите следующую ошибку:

SELECT pgv_get('vars', 'int1', NULL::int);
ERROR:  unrecognized variable "int1"

pgv_get() функция проверяет тип переменной. Если тип переменной не совпадает с типом функции, будет вызвана ошибка:

SELECT pgv_get('vars', 'int1', NULL::text);
ERROR:  variable "int1" requires "integer" value

F.59.5. Функции скалярных переменных #

Функция Возвращает
pgv_set(package text, name text, value anynonarray, is_transactional bool default false) void
pgv_get(package text, name text, var_type anynonarray, strict bool default true) anynonarray

F.59.6. Функции массивов переменных #

Функция Возвращает
pgv_set(package text, name text, value anyarray, is_transactional bool default false) void
pgv_get(package text, name text, var_type anyarray, strict bool default true) anyarray

pgv_set аргументы:

  • package - имя пакета, он будет создан, если не существует.

  • name - имя переменной, она будет создана, если не существует. pgv_set завершится с ошибкой, если переменная уже существует и её транзакционность не соответствует аргументу is_transactional.

  • value - новое значение для переменной. pgv_set завершится с ошибкой, если переменная уже существует и её тип не соответствует типу нового значения.

  • is_transactional - транзакционность вновь созданной переменной, по умолчанию false.

pgv_get аргументы:

  • package - имя существующего пакета. Если пакет не существует, результат зависит от аргумента strict: если он ложный, то pgv_get возвращает NULL, в противном случае происходит ошибка.

  • name - имя существующей переменной. Если переменная не существует, результат зависит от аргумента strict: если он ложный, то pgv_get возвращает NULL, в противном случае происходит ошибка.

  • var_type - тип существующей переменной. Это необходимо для получения правильного возвращаемого типа.

  • strict - передайте false, если pgv_get не должен вызывать ошибку, если переменная или пакет не были созданы ранее, по умолчанию это true.

F.59.7. Устаревшие функции скалярных переменных #

F.59.7.1. Целочисленные переменные #

Функция Возвращает
pgv_set_int(package text, name text, value int, is_transactional bool default false) void
pgv_get_int(package text, name text, strict bool default true) int

F.59.7.2. Текстовые переменные #

Функция Возвращает
pgv_set_text(package text, name text, value text, is_transactional bool default false) void
pgv_get_text(package text, name text, strict bool default true) текст

F.59.7.3. Числовые переменные #

Функция Возвращает
pgv_set_numeric(package text, name text, value numeric, is_transactional bool default false) void
pgv_get_numeric(package text, name text, strict bool default true) числовой

F.59.7.4. Переменные временной метки #

Функция Возвращает
pgv_set_timestamp(package text, name text, value timestamp, is_transactional bool default false) void
pgv_get_timestamp(package text, name text, strict bool default true) метка времени

F.59.7.5. Переменные временной метки с часовым поясом #

Функция Возвращает
pgv_set_timestamptz(package text, name text, value timestamptz, is_transactional bool default false) void
pgv_get_timestamptz(package text, name text, strict bool default true) timestamptz

F.59.7.6. Переменные даты #

Функция Возвращает
pgv_set_date(package text, name text, value date, is_transactional bool default false) void
pgv_get_date(package text, name text, strict bool default true) дата

F.59.7.7. Переменные Jsonb #

Функция Возвращает
pgv_set_jsonb(package text, name text, value jsonb, is_transactional bool default false) void
pgv_get_jsonb(package text, name text, strict bool default true) jsonb

F.59.8. Функции переменных записи #

Следующие функции предоставляются модулем для работы с коллекциями типов записей.

Чтобы использовать функции pgv_update(), pgv_delete() и pgv_select(), необходимы существующие пакет и переменная. В противном случае будет вызвана ошибка. Необходимо установить переменную с помощью функции pgv_insert() для использования этих функций.

pgv_update(), pgv_delete() и pgv_select() функции проверяют тип переменной. Если тип переменной не record, будет вызвана ошибка.

Таблица F.29. Функции переменных записей

Функция

Возвращает

Описание

pgv_insert(package text, name text, r record, is_transactional bool default false)

пусто

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

pgv_update(package text, name text, r record)

логическое значение

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

pgv_delete(package text, name text, value anynonarray)

логическое значение

Удаляет запись с соответствующим первичным ключом (первый столбец r является первичным ключом). Возвращает true, если запись была найдена.

pgv_select(package text, name text)

set of record

Возвращает записи коллекции переменных.

pgv_select(package text, name text, value anynonarray)

запись

Возвращает запись с соответствующим первичным ключом (первая колонка r является первичным ключом).

pgv_select(package text, name text, value anyarray)

set of record

Возвращает записи коллекции переменных с соответствующими первичными ключами (первый столбец r является первичным ключом).


F.59.8.1. Различные функции #

Таблица F.30. Различные функции

Функция

Возвращает

Описание

pgv_exists(package text, name text)

bool

Возвращает true, если пакет и переменная существуют.

pgv_exists(package text)

bool

Возвращает true, если пакет существует.

pgv_remove(package text, name text)

пусто

Удаляет переменную с соответствующим именем. Требуется наличие пакета и переменной, в противном случае будет вызвана ошибка.

pgv_remove(package text)

пусто

Удаляет пакет и все переменные пакета с соответствующим именем. Требуемый пакет должен существовать, в противном случае будет вызвана ошибка.

pgv_free()

пусто

Удаляет все пакеты и переменные.

pgv_list()

таблица (package text, name text, is_transactional bool)

Возвращает набор записей назначенных пакетов и переменных.

pgv_stats()

таблица (package text, allocated_memory bigint)

Возвращает список назначенных пакетов и используемую память в байтах.


F.59.9. Примеры #

Использование функций для работы с скалярными и массивными переменными очень просто:

SELECT pgv_set('vars', 'int1', 101);
SELECT pgv_set('vars', 'text1', 'text variable'::text);

SELECT pgv_get('vars', 'int1', NULL::int);
 pgv_get_int
-------------
         101

SELECT SELECT pgv_get('vars', 'text1', NULL::text);
    pgv_get
---------------
 text variable

SELECT pgv_set('vars', 'arr1', '{101,102}'::int[]);

SELECT pgv_get('vars', 'arr1', NULL::int[]);
  pgv_get
-----------
 {101,102}

Предположим, у нас есть таблица tab:

CREATE TABLE tab (id int, t varchar);
INSERT INTO tab VALUES (0, 'str00'), (1, 'str11');

Затем вы можете использовать функции для работы с переменными-записями:

SELECT pgv_insert('vars', 'r1', tab) FROM tab;

SELECT pgv_select('vars', 'r1');
 pgv_select
------------
 (1,str11)
 (0,str00)

SELECT pgv_select('vars', 'r1', 1);
 pgv_select
------------
 (1,str11)

SELECT pgv_select('vars', 'r1', 0);
 pgv_select
------------
 (0,str00)

SELECT pgv_select('vars', 'r1', ARRAY[1, 0]);
 pgv_select
------------
 (1,str11)
 (0,str00)

SELECT pgv_delete('vars', 'r1', 1);

SELECT pgv_select('vars', 'r1');
 pgv_select
------------
 (0,str00)

Вы можете перечислить пакеты и переменные:

SELECT * FROM pgv_list() order by package, name;
 package | name  | is_transactional
---------+-------+------------------
 vars    | arr1  | f
 vars    | int1  | f
 vars    | r1    | f
 vars    | text1 | f

И получить использованную память в байтах:

SELECT * FROM pgv_stats() order by package;
 package | allocated_memory
---------+------------------
 vars    |            49152

Вы можете удалить переменные или целые пакеты:

SELECT pgv_remove('vars', 'int1');
SELECT pgv_remove('vars');

Вы можете удалить все пакеты и переменные:

SELECT pgv_free();

Если вы хотите использовать переменные с поддержкой транзакций и точек сохранения, вы должны добавить флаг is_transactional = true в качестве последнего аргумента в функции pgv_set() или pgv_insert(). Следующие случаи использования описывают поведение транзакционных переменных:

SELECT pgv_set('pack', 'var_text', 'before transaction block'::text, true);
BEGIN;
SELECT pgv_set('pack', 'var_text', 'before savepoint'::text, true);
SAVEPOINT sp1;
SELECT pgv_set('pack', 'var_text', 'savepoint sp1'::text, true);
SAVEPOINT sp2;
SELECT pgv_set('pack', 'var_text', 'savepoint sp2'::text, true);
RELEASE sp2;
SELECT pgv_get('pack', 'var_text', NULL::text);
    pgv_get
---------------
 savepoint sp2

ROLLBACK TO sp1;
SELECT pgv_get('pack', 'var_text', NULL::text);
     pgv_get
------------------
 before savepoint

ROLLBACK;
SELECT pgv_get('pack', 'var_text', NULL::text);
         pgv_get
--------------------------
 before transaction block

Если вы создаете транзакционную переменную после BEGIN или SAVEPOINT операторов, а затем откатываетесь к предыдущему состоянию - переменная не будет существовать:

BEGIN;
SAVEPOINT sp1;
SAVEPOINT sp2;
SELECT pgv_set('pack', 'var_int', 122, true);
RELEASE SAVEPOINT sp2;
SELECT pgv_get('pack', 'var_int', NULL::int);
pgv_get
---------
     122

ROLLBACK TO sp1;
SELECT pgv_get('pack','var_int', NULL::int);
ERROR:  unrecognized variable "var_int"
COMMIT;

Вы можете отменить удаление транзакционной переменной с помощью ROLLBACK, но если вы удалите весь пакет, все обычные переменные будут удалены навсегда:

SELECT pgv_set('pack', 'var_reg', 123);
SELECT pgv_set('pack', 'var_trans', 456, true);
BEGIN;
SELECT pgv_free();
SELECT * FROM pgv_list();
 package | name | is_transactional
---------+------+------------------
(0 rows)

-- Memory is allocated yet
SELECT * FROM pgv_stats();
 package | allocated_memory
---------+------------------
 pack    |            24576

ROLLBACK;
SELECT * FROM pgv_list();
 package |   name    | is_transactional
---------+-----------+------------------
 pack    | var_trans | t

Если вы создали транзакционную переменную один раз, вы должны использовать флаг is_transactional каждый раз, когда хотите изменить значение переменной с помощью функций pgv_set(), pgv_insert() и устаревших установщиков (например, pgv_set_int()). Если вы попытаетесь изменить эту опцию, вы получите ошибку:

SELECT pgv_insert('pack', 'var_record', row(123::int, 'text'::text), true);

SELECT pgv_insert('pack', 'var_record', row(456::int, 'another text'::text));
ERROR:  variable "var_record" already created as TRANSACTIONAL

Функции pgv_update() и pgv_delete() не требуют этого флага.