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-совместимые команды без необходимости указывать пробелы между токенами.

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

Оператор != при вводе преобразуется в <>, поэтому эти два имени всегда эквивалентны.

Должен быть определён хотя бы один из параметров LEFTARG и RIGHTARG. Для бинарных операторов должны быть определены оба. Для правых унарных операторов следует определить только LEFTARG, а для левых унарных — только RIGHTARG.

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

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

В синтаксисе CREATE OPERATOR ключевые слова FUNCTION и PROCEDURE являются эквивалентными, однако ссылаться необходимо на функцию, а не на процедуру. Использование ключевого слова PROCEDURE является историческим и устаревшим.

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

Чтобы иметь возможность создать оператор, вы должны обладать привилегией USAGE на типы аргументов и возвращаемый тип, а также привилегией EXECUTE на базовую функцию. Если указаны коммутатор или негатор, вы должны владеть этими операторами.

Параметры

  • name
    • Имя создаваемого оператора (может быть квалифицировано именем схемы). Допустимые символы см. в разделе «Описание» выше. Имя может быть квалифицировано схемой, например CREATE OPERATOR myschema.+ (...). В противном случае оператор будет создан в текущей схеме. Два оператора в одной схеме могут иметь одинаковые имена, если они работают с разными типами данных. Это называется перегрузкой.
  • function_name
    • Функция, используемая для реализации этого оператора (должна быть IMMUTABLE функцией).
  • left_type
    • Тип данных левого операнда оператора, если таковой имеется. Этот параметр опускается для левоунарного оператора.
  • right_type
    • Тип данных правого операнда оператора, если таковой имеется. Этот параметр опускается для правоунарного оператора.
  • com_op
    • Коммутатор данного оператора. Необязательное предложение COMMUTATOR указывает оператор, являющийся коммутатором создаваемого оператора. Говорят, что оператор A является коммутатором оператора B, если (x A y) эквивалентно (y B x) для всех возможных значений x и y. Заметьте, что B также является коммутатором A. Например, операторы < и > для определённого типа данных обычно являются коммутаторами друг для друга, а оператор + обычно коммутативен сам с собой. Однако оператор - обычно не является коммутативным ни с чем. Левый тип операнда коммутируемого оператора совпадает с правым типом операнда его коммутатора и наоборот. Поэтому в предложении COMMUTATOR нужно указать только имя оператора-коммутатора.
  • neg_op
    • Негатор данного оператора. Необязательное предложение NEGATOR указывает оператор, являющийся негатором создаваемого оператора. Говорят, что оператор A является негатором оператора B, если оба возвращают логические значения и (x A y) эквивалентно NOT (x B y) для всех возможных входных значений x и y. Заметьте, что B также является негатором A. Например, < и >= часто образуют пару негаторов для большинства типов данных. Негатор оператора должен иметь те же типы левого и/или правого операндов, что и определяемый оператор, поэтому в предложении NEGATOR нужно указать только имя оператора.
  • res_proc
    • Функция оценки селективности ограничивающего условия для этого оператора. Необязательное предложение RESTRICT указывает функцию оценки селективности ограничивающего условия для оператора. (Обратите внимание, что это имя функции, а не оператора.) Предложения RESTRICT имеют смысл только для бинарных операторов, возвращающих логическое значение.
  • join_proc
    • Функция оценки селективности соединения для этого оператора. Необязательное предложение JOIN указывает функцию оценки селективности соединения для оператора. (Обратите внимание, что это имя функции, а не оператора.) Предложения JOIN имеют смысл только для бинарных операторов, возвращающих логическое значение.
  • HASHES
    • Указывает, что этот оператор может поддерживать хеш-соединение. Необязательное предложение HASHES сообщает системе, что допустимо использовать метод хеш-соединения для соединения на основе этого оператора. HASHES имеет смысл только для бинарных операторов, возвращающих логическое значение. Оператор хеш-соединения может возвращать true только для пар левых и правых значений, которые попадают в один и тот же хеш-код. Если два значения помещаются в разные хеш-бакеты, соединение никогда их не сравнит, неявно предполагая, что результат оператора соединения должен быть false. По этой причине указание HASHES никогда не имеет смысла для операторов, не представляющих равенство.
  • MERGES
    • Указывает, что этот оператор может поддерживать слияние при соединении. Присутствие предложения MERGES сообщает системе, что допустимо использовать метод соединения слиянием для соединения на основе этого оператора. MERGES имеет смысл только для бинарных операторов, возвращающих логическое значение, и на практике оператор должен представлять равенство для некоторого типа данных или пары типов данных.

Чтобы указать квалифицированное именем схемы имя оператора в com_op или других необязательных аргументах, используйте синтаксис OPERATOR(), например:

COMMUTATOR = OPERATOR(myschema.===) ,

Замечания

Дополнительную информацию см. в разделе «Пользовательские операторы» документации PostgreSQL.

Все функции, используемые для реализации оператора, должны быть определены как IMMUTABLE.

Невозможно указать приоритет лексического анализа оператора в CREATE OPERATOR, поскольку поведение парсера по приоритетам жёстко задано. Подробности о приоритетах см. в разделе «Приоритет операторов» документации PostgreSQL.

Используйте DROP OPERATOR для удаления пользовательских операторов из базы данных. Используйте ALTER OPERATOR для изменения операторов в базе данных.

Примеры

Следующая команда определяет новый оператор area-equality для типа данных box:

CREATE OPERATOR === (
    LEFTARG = box,
    RIGHTARG = box,
    FUNCTION = area_equal_function,
    COMMUTATOR = ===,
    NEGATOR = !==,
    RESTRICT = area_restriction_function,
    JOIN = area_join_function,
    HASHES, MERGES
);

Следующий пример создаёт оператор для сложения двух комплексных чисел. В примере предполагается, что мы уже создали определение типа complex. Сначала определяется функция, выполняющая работу, затем определяется оператор:

CREATE FUNCTION complex_add(complex, complex)
    RETURNS complex
    AS 'filename', 'complex_add'
    LANGUAGE C IMMUTABLE STRICT;
CREATE OPERATOR + (
    leftarg = complex,
    rightarg = complex,
    procedure = complex_add,
    commutator = +
);

Использование этого оператора в запросе:

SELECT (a + b) AS c FROM test_complex;

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

CREATE OPERATOR является расширением Database относительно стандарта SQL. Стандарт SQL не предусматривает определение пользовательских операторов.

Смотрите также

CREATE FUNCTION, CREATE TYPE, ALTER OPERATOR, CREATE OPERATOR CLASS, DROP OPERATOR