×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

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

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

6.1.92. CREATE TYPE

6.1.92. CREATE TYPE

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 ]
    [ , MULTIRANGE_TYPE_NAME = multirange_type_name ]
)

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 ]
    [ , SUBSCRIPT = subscript_function ]
    [ , INTERNALLENGTH = { internallength | VARIABLE } ]
    [ , PASSEDBYVALUE ]
    [ , ALIGNMENT = alignment ]
    [ , STORAGE = storage ]
    [ , LIKE = like_type ]
    [ , CATEGORY = category ]
    [ , PREFERRED = preferred ]
    [ , DEFAULT = default ]
    [ , ELEMENT = element ]
    [ , DELIMITER = delimiter ]
    [ , COLLATABLE = collatable ]
)

CREATE TYPE name

Описание

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

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

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

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

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

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

Перечисляемые типы

Вторая форма CREATE TYPE создаёт перечисляемый (enum) тип, как описано в Раздел 2.5.7. Для enum-типов указывается список заключённых в кавычки меток, каждая из которых должна быть короче NAMEDATALEN байт (64 байта в стандартной сборке Digital Q.DataBase). (Возможно создание перечисляемого типа с нулём меток, но такой тип нельзя использовать для хранения значений до тех пор, пока с помощью команды ALTER TYPE не будет добавлена хотя бы одна метка.)

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

Третья форма CREATE TYPE создаёт новый диапазонный тип (range), как описано в Раздел 2.5.17.

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

Необязательная функция canonical должна принимать один аргумент определяемого диапазонного типа и возвращать значение того же типа. Она используется для приведения значений диапазона к канонической форме, когда это применимо. Дополнительные сведения см. в Раздел 2.5.17.8. Создание функции canonical немного сложно, поскольку она должна быть определена до объявления диапазонного типа. Чтобы это сделать, необходимо сначала создать тип-оболочку, который является типом-заполнителем, не имеющим свойств, кроме имени и владельца. Это делается командой CREATE TYPE name без дополнительных параметров. Затем функцию можно объявить, используя тип-оболочку в качестве аргумента и результата, и, наконец, диапазонный тип можно объявить с тем же именем. Это автоматически заменяет запись типа-оболочки на корректный диапазонный тип.

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

Необязательный параметр multirange_type_name задаёт имя соответствующего мультидиапазонного типа. Если он не указан, это имя выбирается автоматически следующим образом. Если имя диапазонного типа содержит подстроку range, то имя мультидиапазонного типа формируется заменой подстроки range на multirange в имени диапазонного типа. В противном случае имя мультидиапазонного типа формируется добавлением суффикса _multirange к имени диапазонного типа.

Базовые типы

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

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

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

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

На этом этапе вы можете задаться вопросом, как функции ввода и вывода могут быть объявлены с результатами или аргументами нового типа, когда они должны быть созданы до того, как можно создать новый тип. Ответ заключается в том, что тип сначала должен быть определён как тип-оболочка (shell type), который является типом-заполнителем, не имеющим свойств, кроме имени и владельца. Это делается с помощью команды CREATE TYPE name без дополнительных параметров. Затем C-функции ввода/вывода могут быть определены со ссылкой на тип-оболочку. Наконец, CREATE TYPE с полным определением заменяет запись-оболочку на полное, корректное определение типа, после чего новый тип может использоваться обычным образом.

Необязательные функции type_modifier_input_function и type_modifier_output_function необходимы, если тип поддерживает модификаторы, то есть дополнительные ограничения, прикреплённые к объявлению типа, такие как char(5) или numeric(30,2). Digital Q.DataBase позволяет пользовательским типам принимать одну или несколько простых констант или идентификаторов в качестве модификаторов. Однако эта информация должна быть способна упаковываться в одно неотрицательное целочисленное значение для хранения в системных каталогах. Функции type_modifier_input_function передаются объявленные модификаторы в виде массива cstring. Она должна проверить значения на корректность (выбросив ошибку, если они неверны), и если они корректны, вернуть одно неотрицательное integer значение, которое будет сохранено как «typmod» столбца. Модификаторы типа будут отклонены, если у типа нет type_modifier_input_function. Функция type_modifier_output_function преобразует внутреннее целочисленное значение typmod обратно в правильную форму для отображения пользователю. Она должна возвращать значение cstring, которое является точной строкой для добавления к имени типа; например, функция для numeric может возвращать (30,2). Разрешено опускать type_modifier_output_function, и в этом случае формат отображения по умолчанию — это просто сохранённое целочисленное значение typmod, заключённое в скобки.

Необязательная функция analyze_function выполняет специфичный для типа сбор статистики для столбцов этого типа данных. По умолчанию ANALYZE попытается собрать статистику, используя операторы «равно» и «меньше» типа, если для типа существует класс операторов B-дерева по умолчанию. Для нескалярных типов такое поведение, скорее всего, непригодно, поэтому его можно переопределить, указав пользовательскую функцию анализа. Функция анализа должна быть объявлена как принимающая один аргумент типа internal и возвращающая результат типа boolean. Подробный API для функций анализа приведён в src/include/commands/vacuum.h.

Необязательная функция subscript_function позволяет индексировать (обращаться по индексу) значения типа данных в SQL-командах. Указание этой функции не приводит к тому, что тип считается «настоящим» типом массива; например, он не будет кандидатом на тип результата конструкции ARRAY[]. Но если индексация значения типа является естественной нотацией для извлечения данных из него, то subscript_function может быть написана для определения того, что это означает. Функция индексации должна быть объявлена как принимающая один аргумент типа internal и возвращающая результат типа internal, который является указателем на структуру методов (функций), реализующих индексацию. Подробный API для функций индексации приведён в src/include/nodes/subscripting.h. Также может быть полезно прочитать реализацию массива в src/backend/utils/adt/arraysubs.c, или более простой код в contrib/hstore/hstore_subs.c. Дополнительная информация приведена в Array Types ниже.

Хотя детали внутреннего представления нового типа известны только функциям ввода/вывода и другим функциям, которые вы создаёте для работы с типом, есть несколько свойств внутреннего представления, которые должны быть объявлены для Digital Q.DataBase. Важнейшим из них является internallength. Базовые типы данных могут быть фиксированной длины, в этом случае internallength является положительным целым числом, или переменной длины, что указывается установкой internallength в VARIABLE. (Внутренне это представляется установкой typlen в -1.) Внутреннее представление всех типов переменной длины должно начинаться с 4-байтового целого числа, указывающего общую длину этого значения типа. (Обратите внимание, что поле длины часто кодируется, как описано в Раздел 7.15.2; обращаться к нему напрямую неразумно.)

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

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

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

Все значения storage, отличные от plain, подразумевают, что функции типа данных могут обрабатывать значения, которые были тостированы (toasted), как описано в Раздел 7.15.2 и Раздел 5.1.13.1. Конкретное другое заданное значение лишь определяет стратегию хранения TOAST по умолчанию для столбцов тостируемого типа данных; пользователи могут выбирать другие стратегии для отдельных столбцов с помощью ALTER TABLE SET STORAGE.

Параметр like_type предоставляет альтернативный метод указания основных свойств представления типа данных: скопировать их из некоторого существующего типа. Значения internallength, passedbyvalue, alignment и storage копируются из указанного типа. (Возможно, хотя обычно нежелательно, переопределить некоторые из этих значений, указав их вместе с предложением LIKE.) Указание представления таким способом особенно полезно, когда низкоуровневая реализация нового типа «заимствует» у существующего типа тем или иным образом.

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

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

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

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

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

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

Всякий раз, когда создаётся пользовательский тип, Digital Q.DataBase автоматически создаёт связанный тип массива, имя которого состоит из имени типа элемента с предшествующим символом подчёркивания и усекается при необходимости, чтобы сохранить длину менее NAMEDATALEN байт. (Если сгенерированное имя конфликтует с именем существующего типа, процесс повторяется, пока не найдётся неконфликтующее имя.) Этот неявно созданный тип массива является типом переменной длины и использует встроенные функции ввода и вывода array_in и array_out. Более того, этот тип используется системой для конструкций типа ARRAY[] над пользовательским типом. Тип массива отслеживает любые изменения владельца или схемы его типа элемента и удаляется, если удаляется тип элемента.

Возможно, вы зададитесь вопросом, зачем нужна опция ELEMENT, если система создаёт правильный тип массива автоматически. Основной случай, когда полезно использовать ELEMENT, — это когда вы создаёте тип фиксированной длины, который внутренне представляет собой массив из нескольких одинаковых элементов, и вы хотите разрешить доступ к этим элементам напрямую через индексацию, в дополнение к любым операциям, которые вы планируете предоставить для типа в целом. Например, тип point представляется как просто два числа с плавающей запятой, к которым можно получить доступ с помощью point[0] и point[1]. Обратите внимание, что эта возможность работает только для типов фиксированной длины, внутренняя форма которых в точности представляет собой последовательность одинаковых полей фиксированной длины. По историческим причинам (т.е. это явно ошибка, но уже слишком поздно её менять) индексация типов массивов фиксированной длины начинается с нуля, а не с единицы, как для массивов переменной длины.

Указание опции SUBSCRIPT позволяет индексировать значения типа данных, даже если система в остальном не считает его типом массива. Поведение, описанное выше для массивов фиксированной длины, фактически реализуется функцией-обработчиком SUBSCRIPT raw_array_subscript_handler, которая используется автоматически, если вы указываете ELEMENT для типа фиксированной длины без явного указания SUBSCRIPT.

При указании пользовательской функции SUBSCRIPT нет необходимости указывать ELEMENT, если только функции-обработчику SUBSCRIPT не нужно обращаться к typelem, чтобы узнать, что возвращать. Имейте в виду, что указание ELEMENT приводит к тому, что система предполагает, что новый тип содержит или как-то физически зависит от типа элемента; таким образом, например, изменение свойств типа элемента не будет разрешено, если есть какие-либо столбцы зависимого типа.

Параметры

name

Имя (возможно, с указанием схемы) создаваемого типа.

attribute_name

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

data_type

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

collation

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

label

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

subtype

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

subtype_operator_class

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

canonical_function

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

subtype_diff_function

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

multirange_type_name

Имя соответствующего мультидиапазонного типа.

input_function

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

output_function

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

receive_function

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

send_function

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

type_modifier_input_function

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

type_modifier_output_function

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

analyze_function

Имя функции, которая выполняет статистический анализ для типа данных.

subscript_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' для «пользовательского типа». Другие стандартные коды категорий можно найти в Таблица 7.2.65. Вы также можете выбрать другие символы ASCII для создания пользовательских категорий.

preferred

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

default

Значение по умолчанию для типа данных. Если опущено, значение по умолчанию — NULL.

element

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

delimiter

Символ-разделитель, используемый между значениями в массивах, состоящих из этого типа.

collatable

True, если операции этого типа могут использовать информацию о сортировке. По умолчанию false.

Примечания

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

До версии Digital Q.DataBase 8.3 имя сгенерированного типа массива всегда было в точности именем типа элемента с одним предшествующим символом подчёркивания (_). (Имена типов были, следовательно, ограничены длиной на один символ меньше, чем другие имена.) Хотя это всё ещё обычно так, имя типа массива может отличаться от этого в случае имён максимальной длины или конфликтов с пользовательскими именами типов, начинающимися с подчёркивания. Написание кода, зависящего от этого соглашения, поэтому устарело. Вместо этого используйте pg_type.typarray для нахождения типа массива, ассоциированного с данным типом.

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

До версии Digital Q.DataBase 8.2 синтаксис создания типа-оболочки CREATE TYPE name не существовал. Способом создания нового базового типа было сначала создать его входную функцию. При таком подходе Digital Q.DataBase сначала увидит имя нового типа данных в качестве возвращаемого типа входной функции. Тип-оболочка неявно создаётся в этой ситуации, и затем он может быть указан в определениях оставшихся функций ввода/вывода. Этот подход всё ещё работает, но устарел и может быть запрещён в одном из будущих выпусков. Кроме того, чтобы случайно не засорять каталоги типами-оболочками в результате простых опечаток в определениях функций, тип-оболочка будет создаваться этим способом только когда входная функция написана на C.

В версии Digital Q.DataBase 16 и выше желательно, чтобы входные функции базовых типов возвращали «мягкие» ошибки, используя новый механизм errsave()/ereturn(), а не выбрасывали исключения ereport(), как в предыдущих версиях. Дополнительную информацию см. в src/backend/utils/fmgr/README.

Примеры

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

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

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

Этот пример создаёт перечисляемый тип и использует его в определении таблицы:

CREATE TYPE bug_status AS ENUM ('new', 'open', 'closed');

CREATE TABLE bug (
    id serial,
    description text,
    status bug_status
);

Этот пример создаёт диапазонный тип:

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
);

Дополнительные примеры, включая подходящие функции ввода и вывода, приведены в Раздел 5.1.13.

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

Первая форма команды CREATE TYPE, которая создаёт составной тип, соответствует стандарту SQL. Другие формы являются расширениями Digital Q.DataBase. Оператор CREATE TYPE в стандарте SQL также определяет другие формы, которые не реализованы в Digital Q.DataBase.

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

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению