Привет, Я DocuDroid!
Оценка ИИ поиска
Спасибо за оценку нашего ИИ поиска!
Мы будем признательны, если вы поделитесь своими впечатлениями, чтобы мы могли улучшить наш ИИ поиск для вас и других читателей.
GitHub

CREATE TYPE

Определяет новый тип данных.

Синтаксис

CREATE TYPE <name> AS
    ( <attribute_name> <data_type> [ COLLATE <collation> ] [, ... ] )

CREATE TYPE <name> AS ENUM
    ( [ '<label>' [, ... ] ] )

CREATE TYPE <name> AS RANGE (
    SUBTYPE = <subtype>
    [ , SUBTYPE_OPCLASS = <subtype_operator_class> ]
    [ , COLLATION = <collation> ]
    [ , CANONICAL = <canonical_function> ]
    [ , SUBTYPE_DIFF = <subtype_diff_function> ]
)

CREATE TYPE <name> (
    INPUT = <input_function>,
    OUTPUT = <output_function>
    [, RECEIVE = <receive_function>]
    [, SEND = <send_function>]
    [, TYPMOD_IN = <type_modifier_input_function> ]
    [, TYPMOD_OUT = <type_modifier_output_function> ]
    [, ANALYZE = <analyze_function> ]
    [, INTERNALLENGTH = {<internallength> | VARIABLE}]
    [, PASSEDBYVALUE]
    [, ALIGNMENT = <alignment>]
    [, STORAGE = <storage>]
    [, LIKE = <like_type>]
    [, CATEGORY = <category>]
    [, PREFERRED = <preferred>]
    [, DEFAULT = <default>]
    [, ELEMENT = <element>]
    [, DELIMITER = <delimiter>]
    [, COLLATABLE = <collatable>]
    [, COMPRESSTYPE = <compression_type>]
    [, COMPRESSLEVEL = <compression_level>]
    [, BLOCKSIZE = <blocksize>] )

CREATE TYPE <name>

Описание

Команда CREATE TYPE регистрирует новый тип данных для использования в текущей базе данных. Пользователь, определивший тип, становится его владельцем.

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

Существует пять форм команды CREATE TYPE, как показано в синтаксисе выше. Они создают, соответственно, составной тип (composite), тип перечислений (enumerated), диапазонный тип (range), базовый тип (base) или тип-оболочку (shell). Первые четыре формы рассмотрены ниже. Тип-оболочка — это просто заглушка для типа, который будет определен позже; он создается командой CREATE TYPE без каких-либо параметров, кроме имени типа. Типы-оболочки необходимы в качестве предварительных ссылок при создании диапазонных и базовых типов, как описано в соответствующих разделах.

Составные типы

Первая форма CREATE TYPE создает составной тип. Составной тип задается списком имен атрибутов и типов данных. Для атрибута также можно указать правило сортировки (collation), если его тип данных поддерживает сопоставления. Составной тип по сути аналогичен строковому типу таблицы, но использование CREATE TYPE позволяет избежать создания реальной таблицы, когда требуется лишь определить тип. Отдельный составной тип полезен, например, в качестве типа аргумента или возвращаемого значения функции.

Для создания составного типа необходимо иметь привилегию USAGE на все типы данных атрибутов.

Типы перечислений

Вторая форма CREATE TYPE создает тип перечислений (ENUM), описанный в разделе Enumerated Types документации PostgreSQL. Типы ENUM принимают список меток в кавычках, каждая из которых должна быть короче NAMEDATALEN байт (64 в стандартной сборке).

Можно создать тип перечислений без меток, но такой тип нельзя использовать для хранения значений до тех пор, пока хотя бы одна метка не будет добавлена с помощью ALTER TYPE.

Диапазонные типы

Третья форма CREATE TYPE создает новый диапазонный тип, описанный в разделе Range Types.

Подтип диапазонного типа может быть любым типом, для которого существует класс операторов B-tree (для определения порядка значений диапазонного типа). Обычно используется класс операторов B-tree по умолчанию для подтипа; чтобы использовать нестандартный класс операторов, укажите его имя с помощью subtype_opclass. Если подтип поддерживает сопоставления и вы хотите использовать нестандартное правило сортировки для упорядочивания диапазона, укажите желаемое правило с помощью параметра collation.

Необязательная функция canonical_function должна принимать один аргумент определяемого диапазонного типа и возвращать значение того же типа. Она используется для приведения значений диапазона к канонической форме, когда это применимо. Подробнее см. Defining New Range Types. Создание функции canonical_function — несколько нетривиальная задача, поскольку функция должна быть определена до объявления диапазонного типа. Для этого сначала необходимо создать тип-оболочку — тип-заглушку, у которого нет свойств, кроме имени и владельца. Такой тип создается командой CREATE TYPE <name> без дополнительных параметров. Затем функция может быть объявлена с использованием типа-оболочки в качестве аргумента и результата, и, наконец, диапазонный тип может быть объявлен с тем же именем. Это автоматически заменит запись типа-оболочки на полноценный диапазонный тип.

Необязательная функция subtype_diff должна принимать два значения подтипа в качестве аргументов и возвращать значение double precision, представляющее разницу между двумя заданными значениями. Хотя эта функция необязательна, ее наличие позволяет значительно повысить эффективность GiST-индексов для столбцов диапазонного типа. Подробнее см. Defining New Range Types.

Базовые типы

Четвертая форма CREATE TYPE создает новый базовый тип (скалярный тип). Для создания нового базового типа необходимо быть суперпользователем. Параметры могут указываться в любом порядке, а не только в том, который показан в синтаксисе, и большинство из них являются необязательными. Перед определением типа необходимо зарегистрировать две или более функции (с помощью CREATE FUNCTION). Функции input_function и output_function являются обязательными, а функции receive_function, send_function, type_modifier_input_function, type_modifier_output_function и analyze_function — необязательными. Как правило, эти функции должны быть написаны на C или другом низкоуровневом языке. В Greengage DB любая функция, используемая для реализации типа данных, должна быть определена как IMMUTABLE.

Функция input_function преобразует внешнее текстовое представление типа во внутреннее представление, используемое операторами и функциями, определенными для этого типа. Функция output_function выполняет обратное преобразование. Функция ввода может быть объявлена как принимающая один аргумент типа cstring или как принимающая три аргумента с типами cstring, oid, integer. Первый аргумент — входной текст в виде C-строки, второй — собственный OID типа (за исключением типов массивов, которые вместо этого получают OID типа элемента), а третий — typmod целевого столбца, если он известен (если нет, передается -1). Функция ввода должна возвращать значение самого типа данных. Обычно функцию ввода следует объявлять как STRICT; если она не объявлена таковой, она будет вызвана с NULL в качестве первого параметра при чтении входного значения NULL. В этом случае функция все равно должна возвращать NULL, если только не выдает ошибку. Этот случай предназначен в основном для функций ввода доменов, которым может потребоваться отклонять входные значения NULL. Функция вывода должна быть объявлена как принимающая один аргумент нового типа данных. Функция вывода должна возвращать тип cstring. Функции вывода не вызываются для значений NULL.

Необязательная функция receive_function преобразует внешнее двоичное представление типа во внутреннее представление. Если эта функция не указана, тип не может участвовать в двоичном вводе. Двоичное представление следует выбирать таким, чтобы преобразование во внутреннюю форму было дешевым, но при этом достаточно переносимым. Например, стандартные целочисленные типы данных используют сетевой порядок байтов в качестве внешнего двоичного представления, тогда как внутреннее представление использует порядок байтов, принятый на данной машине. Функция receive_function должна выполнять достаточную проверку корректности значения. Функция receive_function может быть объявлена как принимающая один аргумент типа internal или как принимающая три аргумента с типами internal, oid, integer. Первый аргумент — указатель на буфер StringInfo, содержащий принятую строку байтов; необязательные аргументы те же, что и для функции текстового ввода. Функция receive_function должна возвращать значение самого типа данных. Обычно функцию receive_function следует объявлять как STRICT; если она не объявлена таковой, она будет вызвана с NULL в качестве первого параметра при чтении входного значения NULL. В этом случае функция все равно должна возвращать NULL, если только не выдает ошибку. Этот случай предназначен в основном для функций приема доменов, которым может потребоваться отклонять входные значения NULL. Аналогичным образом необязательная функция send_function преобразует внутреннее представление во внешнее двоичное представление. Если эта функция не указана, тип не может участвовать в двоичном выводе. Функция отправки должна быть объявлена как принимающая один аргумент нового типа данных. Функция отправки должна возвращать тип bytea. Функции отправки не вызываются для значений NULL.

Необязательные функции type_modifier_input_function и type_modifier_output_function требуются, если тип поддерживает модификаторы. Модификаторы — это необязательные ограничения, прикрепленные к объявлению типа, такие как char(5) или numeric(30,2). Хотя Greengage DB позволяет пользовательским типам принимать одну или несколько простых констант или идентификаторов в качестве модификаторов, эта информация должна помещаться в одно неотрицательное целое число для хранения в системных каталогах. Greengage DB передает объявленные модификаторы в type_modifier_input_function в виде массива cstring. Функция ввода модификатора должна проверить значения на корректность и вывести ошибку, если они некорректны. Если значения корректны, функция ввода модификатора возвращает одно неотрицательное целое число, которое Greengage DB сохраняет в столбце typmod. Модификаторы типа отклоняются, если тип не был определен с type_modifier_input_function. Функция type_modifier_output_function преобразует внутреннее целочисленное значение typmod обратно в корректную форму для отображения пользователю. Функция вывода модификатора должна возвращать значение cstring, являющееся точной строкой, которая добавляется к имени типа. Например, функция типа numeric может вернуть (30,2). Функция type_modifier_output_function необязательна. Если она не указана, формат отображения по умолчанию — это сохраненное целочисленное значение typmod в скобках.

Чтобы разрешить кажущуюся циклическую зависимость (функции ввода/вывода требуют тип, который еще не существует), тип сначала определяется как "тип-оболочка" (shell type) — шаблон, у которого есть только имя и владелец. Для этого используется команда CREATE TYPE <name> без дополнительных параметров. Затем функции ввода/вывода можно определить с использованием ссылки на тип-оболочку. Наконец, команда CREATE TYPE с полным определением заменяет запись типа-оболочки полным, корректным определением типа, после чего новый тип можно использовать обычным образом.

Параметр like_type предоставляет альтернативный способ задания базовых свойств представления типа данных: скопировать их из существующего типа. Из указанного типа копируются значения internallength, passedbyvalue, alignment и storage. Хотя обычно это нежелательно, можно переопределить некоторые из этих значений, указав их вместе с выражением LIKE. Определение представления таким способом особенно полезно, когда низкоуровневая реализация нового типа тем или иным образом "паразитирует" на существующем типе.

Хотя детали внутреннего представления нового типа известны только функциям ввода/вывода и другим функциям, созданным для работы с этим типом, несколько свойств внутреннего представления необходимо объявить для Greengage DB. Наиболее важным из них является internallength. Базовые типы данных могут быть фиксированной длины (в этом случае internallength — положительное целое число) или переменной длины (что указывается установкой internallength в VARIABLE). Внутренне это представляется установкой typlen в -1. Внутреннее представление всех типов переменной длины должно начинаться с 4-байтового целого числа, задающего общую длину этого значения типа.

Необязательный флаг PASSEDBYVALUE указывает, что значения этого типа данных передаются по значению, а не по ссылке. Нельзя передавать по значению типы, чье внутреннее представление превышает размер типа Datum (4 байта на большинстве систем, 8 байт на некоторых).

Параметр alignment задает требование к выравниванию при хранении типа данных. Допустимые значения соответствуют выравниванию по границам 1, 2, 4 или 8 байт. Обратите внимание, что типы переменной длины должны иметь выравнивание не менее 4, так как они обязательно содержат int4 в качестве первого компонента.

Параметр storage позволяет выбрать стратегию хранения для типов данных переменной длины. Для типов фиксированной длины допускается только plain. Значение plain указывает, что данные этого типа всегда будут храниться встроенно (inline) без сжатия. Значение extended указывает, что система сначала попытается сжать длинное значение, а если оно все еще слишком велико, переместит его из основной строки таблицы. Значение external позволяет переместить значение из основной таблицы, но система не будет пытаться его сжимать. Значение main допускает сжатие, но не рекомендует перемещение значения из основной таблицы. Элементы данных с этой стратегией хранения все же могут быть перемещены из основной таблицы, если нет другого способа уместить строку, но они сохраняются в основной таблице приоритетнее, чем элементы extended и external.

Можно указать значение по умолчанию на случай, если пользователь хочет, чтобы столбцы данного типа по умолчанию принимали значение, отличное от null. Значение по умолчанию задается ключевым словом DEFAULT. Такое значение по умолчанию может быть переопределено явным выражением DEFAULT, привязанным к конкретному столбцу.

Чтобы указать, что тип является массивом, укажите тип элементов массива с помощью ключевого слова ELEMENT. Например, чтобы определить массив 4-байтовых целых чисел (int4), укажите ELEMENT = int4. Подробнее о типах массивов см. ниже.

Параметры category и preferred могут использоваться для управления тем, какое неявное приведение типов Greengage DB применяет в неоднозначных ситуациях. Каждый тип данных принадлежит к категории, обозначаемой одним символом ASCII, и каждый тип является "предпочтительным" или нет в своей категории. Анализатор запросов предпочитает приведение к предпочтительным типам (но только из других типов той же категории), когда это правило помогает разрешить перегруженные функции или операторы. Для типов, не имеющих неявных приведений к другим типам или от них, достаточно оставить настройки по умолчанию. Однако для группы связанных типов с неявными приведениями часто полезно пометить их все как принадлежащие к одной категории и выбрать один или два "наиболее общих" типа в качестве предпочтительных в данной категории. Параметр category особенно полезен при добавлении пользовательского типа к существующей встроенной категории, такой как числовые или строковые типы. Также можно создавать полностью пользовательские категории типов. Для именования такой категории выберите любой символ ASCII, кроме заглавной буквы.

Чтобы указать разделитель между значениями во внешнем представлении массивов данного типа, параметру delimiter можно задать конкретный символ. Разделитель по умолчанию — запятая (,). Обратите внимание, что разделитель связан с типом элемента массива, а не с самим типом массива.

Если необязательный логический параметр collatable равен true, определения столбцов и выражения данного типа могут содержать информацию о сопоставлении через выражение COLLATE. Реализация функций, работающих с этим типом, должна самостоятельно учитывать информацию о сопоставлении; это не происходит автоматически при простой пометке типа как поддерживающего сопоставления.

Типы массивов

При создании пользовательского типа Greengage DB автоматически создает соответствующий тип массива, имя которого состоит из имени типа-элемента с добавлением подчеркивания в начале и при необходимости усекается, чтобы его длина не превышала число байт, заданных в константе NAMEDATALEN. Если сгенерированное имя конфликтует с существующим именем типа, процесс повторяется до нахождения неконфликтующего имени. Этот неявно созданный тип массива имеет переменную длину и использует встроенные функции ввода и вывода array_in и array_out. Тип массива отслеживает любые изменения владельца или схемы типа элемента и удаляется при удалении типа элемента.

Может возникнуть резонный вопрос: зачем нужен параметр ELEMENT, если система автоматически создает правильный тип массива? Единственный случай, когда полезно использовать ELEMENT, — это создание типа фиксированной длины, который внутренне представляет собой массив одинаковых элементов, и вы хотите разрешить доступ к этим элементам по индексу, в дополнение к любым операциям, предусмотренным для типа в целом. Например, тип point представлен просто двумя числами с плавающей запятой, к каждому из которых можно обратиться через point[0] и point[1]. Обратите внимание, что эта возможность работает только для типов фиксированной длины, внутренняя форма которых представляет собой последовательность одинаковых полей фиксированной длины. Тип переменной длины с поддержкой индексации должен иметь обобщенное внутреннее представление, используемое функциями array_in и array_out. По историческим причинам индексация массивов фиксированной длины начинается с нуля, а не с единицы, как для массивов переменной длины.

Параметры

Параметр Описание

name

Имя создаваемого типа (опционально с указанием схемы)

attribute_name

Имя атрибута (столбца) составного типа

data_type

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

collation

Имя существующего правила сортировки, которое будет связано со столбцом составного типа или с диапазонным типом

label

Строковый литерал, представляющий текстовую метку, связанную с одним значением типа перечислений

subtype

Имя типа элемента, диапазоны которого будет представлять диапазонный тип

subtype_operator_class

Имя класса операторов B-tree для подтипа

canonical_function

Имя функции канонизации для диапазонного типа

subtype_diff_function

Имя функции разности для подтипа

input_function

Имя функции, преобразующей данные из внешней текстовой формы типа в его внутреннюю форму

output_function

Имя функции, преобразующей данные из внутренней формы типа в его внешнюю текстовую форму

receive_function

Имя функции, преобразующей данные из внешней двоичной формы типа в его внутреннюю форму

send_function

Имя функции, преобразующей данные из внутренней формы типа в его внешнюю двоичную форму

type_modifier_input_function

Имя функции, преобразующей массив модификаторов типа во внутреннюю форму

type_modifier_output_function

Имя функции, преобразующей внутреннюю форму модификаторов типа во внешнюю текстовую форму

internallength

Числовая константа, задающая длину внутреннего представления нового типа в байтах. По умолчанию предполагается переменная длина

alignment

Требование к выравниванию при хранении типа данных. Может иметь одно из следующих значений: char, int2, int4 или double. По умолчанию — int4

storage

Стратегия хранения для типа данных. Может иметь одно из следующих значений: plain, external, extended или main. По умолчанию — plain

like_type

Имя существующего типа данных, представление которого будет использовано для нового типа. Значения internallength, passedbyvalue, alignment и storage копируются из указанного типа, если они не переопределены явно в данной команде CREATE TYPE

category

Код категории (один символ ASCII) для данного типа. По умолчанию — U, что означает пользовательский тип. Вы также можете назначить неиспользуемые символы ASCII создаваемым вами пользовательским категориям

preferred

Укажите true, если данный тип является предпочтительным в своей категории типов, иначе false. Значение по умолчанию — false. Будьте осторожны при создании нового предпочтительного типа в существующей категории типов — это может привести к неожиданному изменению поведения

default

Значение по умолчанию для типа данных. Если не указано, по умолчанию используется null

element

Создаваемый тип является массивом; этот параметр задает тип элементов массива

delimiter

Символ-разделитель между значениями в массивах данного типа

collatable

Укажите true, если операции с данным типом могут использовать информацию о сопоставлении. По умолчанию — false

compression_type

Установите значение ZLIB (по умолчанию), ZSTD или RLE_TYPE, чтобы указать тип сжатия, используемый в столбцах данного типа

compression_level

Для сжатия Zstd установите целочисленное значение от 1 (самое быстрое сжатие) до 19 (наивысшая степень сжатия). Для сжатия zlib допустимый диапазон — от 1 до 9. Для RLE_TYPE уровень сжатия может быть задан целочисленным значением от 1 (самое быстрое сжатие) до 6 (наивысшая степень сжатия). Уровень сжатия по умолчанию — 1

blocksize

Задает размер каждого блока в столбце в байтах. BLOCKSIZE должен быть в диапазоне от 8192 до 2097152 байт и быть кратным 8192. Размер блока по умолчанию — 32768

Примечания

Имена пользовательских типов не могут начинаться с символа подчеркивания (_) и могут содержать не более 62 символов (или, в общем случае, NAMEDATALEN - 2 вместо NAMEDATALEN - 1 символов, допустимых для других имен). Имена типов, начинающиеся с подчеркивания, зарезервированы для внутренне создаваемых имен типов массивов.

Greengage DB не поддерживает добавление параметров хранения для строковых или составных типов.

Параметры хранения, определенные на уровне таблицы и столбца, переопределяют параметры хранения по умолчанию, заданные для скалярного типа.

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

Примеры

Создать составной тип и использовать его в определении функции:

CREATE TYPE compfoo AS
(
    f1 int,
    f2 text
);

CREATE FUNCTION getfoo()
    RETURNS SETOF compfoo
AS
$$
SELECT fooid, fooname
FROM foo
$$ LANGUAGE SQL;

Создать тип перечислений mood и использовать его в определении таблицы:

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');

CREATE TABLE person
(
    name         text,
    current_mood mood
);

INSERT INTO person
VALUES ('Moe', 'happy');

SELECT * FROM person
WHERE current_mood = 'happy';
 name | current_mood
------+--------------
 Moe  | happy
(1 row)

Создать диапазонный тип:

CREATE TYPE float8_range AS RANGE
(
    subtype = float8,
    subtype_diff = float8mi
);

Создать базовый тип данных box и использовать его в определении таблицы:

CREATE TYPE box;

CREATE FUNCTION my_box_in_function(cstring)
    RETURNS box
AS <...>;

CREATE FUNCTION my_box_out_function(box)
    RETURNS cstring
AS <...>;

CREATE TYPE box
(
    INTERNALLENGTH = 16,
    INPUT = my_box_in_function,
    OUTPUT = my_box_out_function
);

CREATE TABLE myboxes
(
    id          integer,
    description box
);

Если бы внутренняя структура box представляла собой массив из четырех элементов float4, можно было бы вместо этого использовать:

CREATE TYPE box
(
    INTERNALLENGTH = 16,
    INPUT = my_box_in_function,
    OUTPUT = my_box_out_function,
    ELEMENT = float4
);

что позволило бы обращаться к компонентам значения box по индексу. В остальном поведение типа было бы таким же.

Создать тип для больших объектов и использовать его в определении таблицы:

CREATE TYPE bigobj
(
    INPUT = lo_filein,
    OUTPUT = lo_fileout,
    INTERNALLENGTH = VARIABLE
);

CREATE TABLE big_objs
(
    id  integer,
    obj bigobj
);

Совместимость

Первая форма команды CREATE TYPE, создающая составной тип, соответствует стандарту SQL. Остальные формы являются расширениями Greengage DB. Оператор CREATE TYPE в стандарте SQL также определяет другие формы, которые не реализованы в Greengage DB.

Возможность создания составного типа без атрибутов является отклонением от стандарта, специфичным для Greengage DB (аналогично такому же случаю в CREATE TABLE).

См. также