CREATE OPERATOR
Эта страница переведена при помощи нейросети GigaChat.
CREATE OPERATOR
— создание нового оператора.
Синтаксис
CREATE OPERATOR name (
{FUNCTION|PROCEDURE} = function_name
[, LEFTARG = left_type ] [, RIGHTARG = right_type ]
[, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
[, RESTRICT = res_proc ] [, JOIN = join_proc ]
[, HASHES ] [, MERGES ]
)
Описание
CREATE OPERATOR
создает новый оператор с заданным именем. Пользователь, создавший оператор, становится его владельцем. Если указанна схема, оператор создается в этой схеме, иначе — в текущей.
Имя оператора может состоять максимум из NAMEDATALEN - 1
символов (по умолчанию — 63). Допустимыми являются только следующие символы:
+ - * / < > = ~ ! @ # % ^ & | ` ?
Есть несколько ограничений на допустимые имена операторов:
-
--
и/*
не могут присутствовать в имени оператора, поскольку интерпретируются как начало комментария. -
Многосимвольное имя не может заканчиваться на
+
или-
, если при этом в нем нет хотя бы одного символа из следующего набора:~ ! @ # % ^ & | ` ?
Например,
@-
— допустимое имя, а*-
— нет. Это сделано для совместимости с синтаксисом SQL без необходимости использовать пробелы между компонентами. -
Символ
=>
зарезервирован синтаксисом SQL и не может использоваться как имя оператора.
Оператор !=
автоматически интерпретируется как <>
, оба варианта считаются эквивалентными.
Для бинарного оператора необходимо указать оба аргумента — LEFTARG
и RIGHTARG
. Для префиксного оператора указывается только RIGHTARG
. Указанная функция function_name
должна быть создана заранее через CREATE FUNCTION
и принимать соответствующее число аргументов (один или два) указанных типов.
В синтаксисе CREATE OPERATOR
ключевые слова FUNCTION
и PROCEDURE
эквивалентны, однако указывается всегда именно функция, а не процедура. Использование PROCEDURE
считается устаревшим.
Дополнительные параметры позволяют оптимизировать выполнение запросов с использованием этого оператора. Подробности описаны в разделе «Информация для оптимизации операторов» документации PostgreSQL.
Для создания оператора необходимо обладать привилегией USAGE
на типы аргументов и возвращаемое значение, а также привилегией EXECUTE
на нижележащую функцию. Если указывается коммутирующий или обратный оператор, необходимо быть их владельцем.
Параметры
name
- Имя оператора, который должен быть создан. Может быть квалифицировано схемой, например:
CREATE OPERATOR myschema.+ (...)
. Операторы в одной схеме могут иметь одинаковое имя, если они работают с разными типами данных (перегрузка).
function_name
- Функция, реализующая поведение оператора.
left_type
- Тип данных левого операнда оператора, если таковой имеется. Для префиксных операторов не указывается.
right_type
- Тип данных правого операнда оператора.
com_op
- Оператор, коммутирующий для данного.
neg_op
- Оператор, обратный для данного.
res_proc
- Функция оценки селективности ограничений для данного оператора.
join_proc
- Функция оценки селективности соединений для этого оператора.
HASHES
- Поддержка хеш-соединений оператором.
MERGES
- Поддержка соединений слиянием оператором.
Чтобы указать имя оператора с указанием схемы в com_op
или другом дополнительном аргументе, используйте конструкцию OPERATOR(...)
, например:
COMMUTATOR = OPERATOR(myschema.===) ,
Примечания
См. разделы «Пользовательские операторы» и «Информация для оптимизации операторов» для получения дополнительной информации.
Когда определяется оператор, коммутирующий сам для себя, то делаете именно это. Когда определяется пара коммутативных операторов, дело немного сложнее: как первый из них может ссылаться на другой, который еще не определили? Существует три решения этой проблемы:
Один способ — опустить пункт COMMUTATOR
в первом операторе, который определяете, а затем включить его в определение второго оператора. Поскольку PostgreSQL знает, что коммутативные операторы идут парами, когда он видит второе определение, система автоматически возвращается назад и заполняет отсутствующий пункт COMMUTATOR в первом определении.
Другой, более простой способ — просто включить пункты COMMUTATOR
в оба определения. Когда PostgreSQL обрабатывает первое определение и понимает, что COMMUTATOR
относится к несуществующему оператору, система создает фиктивную запись для этого оператора в системном каталоге. Эта фиктивная запись будет содержать действительные данные только для имени оператора, типов левого и правого операндов и владельца, поскольку именно это PostgreSQL может вывести на данном этапе. Запись каталога первого оператора будет связана с этой фиктивной записью. Позже, при определении второго оператора, система обновляет фиктивную запись дополнительными сведениями из второго определения. Если попытаться использовать фиктивный оператор до того, как он был заполнен, появится сообщение об ошибке.
В качестве альтернативы оба оператора могут быть определены без пунктов COMMUTATOR
, после чего можно воспользоваться пунктом ALTER OPERATOR
, чтобы установить их связи с коммутаторами. Достаточно указать ALTER
хотя бы один элемент пары.
Во всех трех случаях нужно владеть обоими операторами, чтобы пометить их как коммутаторы.
Пары отрицательных операторов могут быть определены теми же методами, что и для пар коммутаторов.
Указать лексический приоритет оператора в CREATE OPERATOR
невозможно — приоритет строго задается в синтаксическом анализаторе.
Параметры SORT1
, SORT2
, LTCMP
и GTCMP
ранее предназначались для задания имен операторов сортировки, ассоциированных с оператором, поддерживающим соединение слиянием. Это больше не требуется — сведения о таких операторах извлекаются из семейств операторов B-tree. Если MERGES
явно не указан, указанные параметры игнорируются.
Удаление пользовательских операторов осуществляется с помощью DROP OPERATOR. Для изменения оператора используется ALTER OPERATOR.
Примеры
Создание нового оператора, проверяющего равенство площадей, для типа box
:
CREATE OPERATOR === (
LEFTARG = box,
RIGHTARG = box,
FUNCTION = area_equal_function,
COMMUTATOR = ===,
NEGATOR = !==,
RESTRICT = area_restriction_function,
JOIN = area_join_function,
HASHES, MERGES
);
Совместимость
CREATE OPERATOR
является расширением для PostgreSQL. В стандарте SQL нет положений для операторов, определяемых пользователем.