5.4. Генерируемые столбцы#

5.4. Генерируемые столбцы

5.4. Генерируемые столбцы #

Генерируемый столбец — это специальный столбец, которая всегда вычисляется на основе других столбцов. Таким образом, для столбцов он является тем же, чем представление (view) является для таблиц. Существует два типа генерируемых столбцов: хранимые и виртуальные. Сохраняемый генерируемый столбец вычисляется при записи (вставке или обновлении) и занимает место в хранилище так же, как обычный столбец. Виртуальный генерируемый столбец не занимает места в хранилище и вычисляется при чтении. Таким образом, виртуальный генерируемый столбец похож на представление, а хранимый генерируемый столбец похож на материализованное представление (за исключением того, что он всегда обновляется автоматически).

Для создания генерируемого столбца используйте предложение GENERATED ALWAYS AS в команде CREATE TABLE, например:

CREATE TABLE people (
    ...,
    height_cm numeric,
    height_in numeric GENERATED ALWAYS AS (height_cm / 2.54)
);

Генерируемый столбец по умолчанию является виртуальным. Используйте ключевые слова VIRTUAL или STORED, чтобы явно указать тип. См. CREATE TABLE для получения дополнительных сведений.

Столбец, созданный автоматически, не может быть записан напрямую. В командах INSERT или UPDATE нельзя указывать значение для столбца, созданного автоматически, но можно использовать ключевое слово DEFAULT.

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

Несколько ограничений применяются к определению генерируемых столбцов и таблиц, включающих генерируемые столбцы:

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

  • Генерирующее выражение не может ссылаться на другой генерируемый столбец.

  • Генерирующее выражение не может ссылаться на системный столбец, за исключением столбца tableoid.

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

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

  • Столбец, созданный автоматически, не может быть частью ключа разделения.

  • Внешние таблицы могут иметь генерируемые столбцы. См. CREATE FOREIGN TABLE для получения подробной информации.

  • Для наследования и разбиения на секции:

    • Если родительский столбец является генерируемым столбцом, дочерний столбец также должен быть генерируемым столбцом того же типа (хранимым или виртуальным); однако дочерний столбец может иметь другое генерирующее выражение.

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

    • Если родительский столбец не является генерируемым столбцом, его дочерний столбец также не должен быть генерируемым.

    • Для унаследованных таблиц, если определение столбца дочерней таблицы задано без предложения GENERATED в CREATE TABLE ... INHERITS, то его предложение GENERATED будет автоматически скопировано из родительской таблицы. ALTER TABLE ... INHERIT будет требовать, чтобы родительские и дочерние столбцы совпадали по статусу генерирования, но не будет требовать совпадения соответствующих генерирующих выражений.

    • Аналогично для секционированных таблиц, если вы пишете определение дочернего столбца без предложения GENERATED в CREATE TABLE ... PARTITION OF, то его предложение GENERATED будет автоматически скопировано от родителя. ALTER TABLE ... ATTACH PARTITION будет требовать, чтобы родительские и дочерние столбцы совпадали по статусу генерирования, но не будет требовать совпадения соответствующих генерирующих выражений.

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

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

  • Права доступа к генерируемым столбцам отдельны от прав доступа к базовым столбцам. Таким образом, можно настроить определенную роль так, чтобы она могла прочитать генерируемый столбец, но не базовые столбцы.

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

  • Права на вызов функций, используемых в генерирующих выражениях, проверяются при фактическом выполнении выражения — соответственно при записи или чтении — так, как если бы генерирующее выражение вызывалось напрямую из запроса с использованием генерируемого столбца. Пользователь генерируемого столбца должен иметь разрешения на вызов всех функций, используемых в генерирующем выражении. Функции в генерирующем выражении выполняются с привилегиями пользователя, выполняющего запрос, или владельца функции, в зависимости от того, определены ли функции как SECURITY INVOKER или SECURITY DEFINER.

  • Генерируемые столбцы, по определению, обновляются после выполнения триггеров BEFORE. Поэтому изменения, внесенные в базовые столбцы в триггере BEFORE, будут отражены в генерируемых столбцах. Но получить доступ к генерируемым столбцам в триггерах BEFORE нельзя.

  • Генерируемые столбцы могут учувствовать в логической репликации в соответствии с параметром CREATE PUBLICATION publish_generated_columns или путем включения их в список столбцов команды CREATE PUBLICATION. В настоящее время поддерживается только для сохранённых генерируемых столбцов. Подробнее см. Раздел 28.6.