CREATE OPERATOR

CREATE OPERATOR — definir un nuevo operador

Synopsis

CREATE OPERATOR nombre (
    {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 ]
)

Descripción

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.

Parámetros

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ón

La función utilizada para implementar este operador.

tipo_izq

El tipo de datos del operando izquierdo del operador, si lo hay. Esta opción se omitiría para un operador de prefijo.

tipo_der

El tipo de datos del operando derecho del operador.

op_conmutador

El conmutador de este operador.

op_negador

El negador de este operador.

proc_restricción

La función estimadora de selectividad de restricción para este operador.

proc_unión

La función estimadora de selectividad de unión para este operador.

HASHES

Indica que este operador puede admitir una unión hash (hash join).

MERGES

Indica 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.===) ,

Notas

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.

Ejemplos

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

Compatibilidad

CREATE OPERATOR es una extensión de PostgreSQL. No hay disposiciones para operadores definidos por el usuario en el estándar SQL.

Consulte también

ALTER OPERATOR, CREATE OPERATOR CLASS, DROP OPERATOR