CREATE OPERATOR — definir un nuevo operador
CREATE OPERATORnombre( {FUNCTION|PROCEDURE} =nombre_función[, LEFTARG =tipo_izq] [, RIGHTARG =tipo_der] [, COMMUTATOR =op_conmutador] [, NEGATOR =op_negador] [, RESTRICT =proc_restricción] [, JOIN =proc_unión] [, HASHES ] [, MERGES ] )
CREATE OPERATOR define un nuevo operador,
nombre. El usuario que
define un operador se convierte en su propietario. Si se proporciona un
nombre de esquema, el operador se crea en el esquema especificado. De lo
contrario, se crea en el esquema actual.
El nombre del operador es una secuencia de hasta NAMEDATALEN-1
(63 por defecto) caracteres de la siguiente lista:
+ - * / < > = ~ ! @ # % ^ & | ` ?
Existen algunas restricciones en la elección del nombre:
-- y /* no pueden aparecer en ninguna parte del nombre de un operador,
ya que se interpretarían como el comienzo de un comentario.
El nombre de un operador multicarácter no puede terminar en + o
-, a menos que el nombre también contenga al menos uno de estos caracteres:
~ ! @ # % ^ & | ` ?
Por ejemplo, @- es un nombre de operador permitido,
pero *- no lo es. Esta restricción permite a
PostgreSQL analizar comandos compatibles con SQL sin
requerir espacios entre tokens.
El símbolo => está reservado por la gramática SQL,
por lo que no se puede utilizar como nombre de operador.
El operador != se mapea a <> en la entrada,
por lo que estos dos nombres son siempre equivalentes.
Para operadores binarios, se deben definir tanto LEFTARG como
RIGHTARG. Para operadores de prefijo solo debe definirse
RIGHTARG. La función nombre_función
debe haber sido definida previamente mediante CREATE FUNCTION y
debe estar definida para aceptar el número correcto de argumentos (uno o dos) de
los tipos indicados.
En la sintaxis de CREATE OPERATOR, las palabras clave
FUNCTION y PROCEDURE son equivalentes,
pero la función referenciada debe ser en cualquier caso una función, no un procedimiento.
El uso de la palabra clave PROCEDURE aquí es histórico y está obsoleto.
Las demás cláusulas especifican atributos opcionales de optimización del operador. Su significado se detalla en la Section 36.15.
Para poder crear un operador, debes tener el privilegio USAGE
en los tipos de argumentos y en el tipo de retorno, así como el privilegio
EXECUTE en la función subyacente. Si se especifica un operador
conmutador o negador, debes ser el propietario de esos operadores.
nombre
El nombre del operador que se va a definir. Consulta más arriba los caracteres permitidos.
El nombre puede estar calificado por esquema, por ejemplo
CREATE OPERATOR mi_esquema.+ (...). Si no es así, el operador se crea
en el esquema actual. Dos operadores en el mismo esquema pueden tener el mismo nombre si
operan sobre diferentes tipos de datos. Esto se conoce como sobrecarga.
nombre_funciónLa función utilizada para implementar este operador.
tipo_izqEl tipo de datos del operando izquierdo del operador, si lo hay. Esta opción se omitiría para un operador de prefijo.
tipo_derEl tipo de datos del operando derecho del operador.
op_conmutadorEl conmutador de este operador.
op_negadorEl negador de este operador.
proc_restricciónLa función estimadora de selectividad de restricción para este operador.
proc_uniónLa función estimadora de selectividad de unión para este operador.
HASHESIndica que este operador puede admitir una unión hash (hash join).
MERGESIndica que este operador puede admitir una unión por mezcla (merge join).
Para proporcionar un nombre de operador calificado por esquema en op_conmutador u otros argumentos opcionales, utiliza
la sintaxis OPERATOR(), por ejemplo:
COMMUTATOR = OPERATOR(mi_esquema.===) ,
Consulta la Section 36.14 y la Section 36.15 para obtener más información.
Cuando estás definiendo un operador autoconmutativo, simplemente lo haces. Cuando estás definiendo un par de operadores conmutativos, la cosa es un poco más complicada: ¿cómo puede el primero que se define hacer referencia al otro, que aún no has definido? Existen tres soluciones para este problema:
Una forma es omitir la cláusula COMMUTATOR en el primer operador que definas,
y luego proporcionar una en la definición del segundo operador. Dado que
PostgreSQL sabe que los operadores conmutativos vienen en pares, cuando
vea la segunda definición regresará automáticamente y completará la cláusula
COMMUTATOR faltante en la primera definición.
Otra forma más directa es simplemente incluir cláusulas COMMUTATOR en ambas
definiciones. Cuando PostgreSQL procesa la primera definición y se da
cuenta de que COMMUTATOR hace referencia a un operador inexistente, el sistema
creará una entrada ficticia (dummy) para ese operador en el catálogo del sistema. Esta entrada
ficticia tendrá datos válidos únicamente para el nombre del operador, los tipos de operandos izquierdo
y derecho, y el propietario, ya que es todo lo que PostgreSQL puede deducir
en este punto. La entrada del catálogo del primer operador se vinculará a esta entrada ficticia.
Más tarde, cuando definas el segundo operador, el sistema actualizará la entrada ficticia con la
información adicional de la segunda definición. Si intentas usar el operador ficticio antes de que
se haya completado, simplemente obtendrás un mensaje de error.
Alternativamente, ambos operadores se pueden definir sin cláusulas COMMUTATOR
y luego se puede usar ALTER OPERATOR para establecer sus vínculos conmutadores.
Basta con aplicar ALTER a cualquiera de los dos miembros del par.
En los tres casos, debes ser el propietario de ambos operadores para poder marcarlos como conmutadores.
Los pares de operadores negadores se pueden definir utilizando los mismos métodos que para los pares conmutadores.
No es posible especificar la precedencia léxica de un operador en CREATE OPERATOR,
porque el comportamiento de precedencia del analizador está codificado de forma fija. Consulta la
Section 4.1.6 para obtener detalles de precedencia.
Las opciones obsoletas SORT1, SORT2, LTCMP,
y GTCMP se utilizaban anteriormente para especificar los nombres de los operadores
de ordenamiento asociados con un operador que se puede unir mediante mezcla (merge-joinable). Esto ya no
es necesario, ya que la información sobre los operadores asociados se encuentra buscando en las familias
de operadores B-tree en su lugar. Si se proporciona una de estas opciones, se ignora, excepto para establecer
implícitamente MERGES como verdadero.
Utiliza DROP OPERATOR para eliminar operadores
definidos por el usuario de una base de datos. Utiliza ALTER OPERATOR
para modificar operadores en una base de datos.
El siguiente comando define un nuevo operador, igualdad de área, para el tipo de datos 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 es una extensión de PostgreSQL.
No hay disposiciones para operadores definidos por el usuario en el estándar SQL.