CREATE OPERATOR

CREATE OPERATOR — define um novo operador

Sinopse

CREATE OPERATOR nome (
    {FUNCTION|PROCEDURE} = nome_da_função
    [, LEFTARG = tipo_de_dados_op_esquerdo ]
    [, RIGHTARG = tipo_de_dados_op_direito ]
    [, COMMUTATOR = operador_comutador ]
    [, NEGATOR = negador_operador ]
    [, RESTRICT = estimador_de_seletividade_de_restrição ]
    [, JOIN = estimador_de_seletividade_de_junção ]
    [, HASHES ] [, MERGES ]
)

Descrição

O comando CREATE OPERATOR define um novo operador. O usuário que define o operador torna-se seu dono. Se for fornecido um nome de esquema, o operador será criado no esquema especificado. Caso contrário, será criado no esquema corrente.

O nome do operador é uma sequência de até NAMEDATALEN-1 (63, por padrão) caracteres da seguinte lista:

+ - * / < > = ~ ! @ # % ^ & | ` ?

Existem algumas restrições na escolha do nome:

  • -- e /* não podem aparecer em nenhum lugar no nome do operador, porque são considerados o início de um comentário.

  • Um nome de operador com vários caracteres não pode terminar em + ou -, a menos que o nome também contenha pelo menos um dos seguintes caracteres:

    ~ ! @ # % ^ & | ` ?
    

    Por exemplo, @- é um nome de operador permitido, mas *- não é. Esta restrição permite que o PostgreSQL analise comandos compatíveis com o SQL sem exigir espaços entre os tokens.

  • O símbolo => é reservado pela gramática SQL, portanto não pode ser usado como nome de operador.

O operador != é mapeado para <> na entrada, então estes dois nomes são sempre equivalentes.

Para operadores binários, tanto LEFTARG quanto RIGHTARG devem ser definidos. Para operadores de prefixo deve ser definido apenas o RIGHTARG. A função nome_da_função deve ter sido previamente definida usando o comando CREATE FUNCTION, e deve ser definida aceitando o número correto de argumentos (um ou dois) dos tipos de dados indicados.

Na sintaxe do comando CREATE OPERATOR, as palavras-chave FUNCTION e PROCEDURE são equivalentes, mas a função referenciada deve, em qualquer um dos casos, ser uma função, e não um procedimento. O uso da palavra-chave PROCEDURE aqui é histórico e está em obsolescência.

As demais cláusulas especificam atributos opcionais de otimização do operador. Seus significados são detalhados na Seção 36.15.

Para poder criar um operador, é necessário ter o privilégio USAGE nos tipos de dados dos argumentos, e no tipo de dados de retorno, bem como o privilégio EXECUTE na função subjacente. Se for especificado um operador comutador ou negador, é necessário ser o dono desses operadores.

Parâmetros

nome

O nome do operador a ser definido. Veja acima os caracteres permitidos. O nome pode ser qualificado pelo esquema, por exemplo, CREATE OPERATOR meu_esquema.+ (...). Se não for, o operador será criado no esquema corrente. Dois operadores no mesmo esquema podem ter o mesmo nome se operarem em tipos de dados diferentes. Isto é chamado de sobrecarga.

nome_da_função

O nome da função usada para implementar este operador.

tipo_de_dados_op_esquerdo

O tipo de dados do operando esquerdo do operador, se houver. Esta opção seria omitida para um operador de prefixo.

tipo_de_dados_op_direito

O tipo de dados do operando direito do operador.

operador_comutador

O comutador desse operador.

negador_operador

O negador desse operador.

estimador_de_seletividade_de_restrição

O nome da função estimadora de seletividade de restrição para este operador.

estimador_de_seletividade_de_junção

O nome da função estimadora de seletividade de junção para este operador.

HASHES

Indica que este operador oferece suporte a junção por hash.

MERGES

Indica que este operador oferece suporte a junção por mesclagem.

Para fornecer um nome de operador qualificado pelo esquema em com_op, ou em outros argumentos opcionais, é usada a sintaxe de OPERATOR(). Por exemplo:

COMMUTATOR = OPERATOR(meu_esquema.===) ,

Notas

Veja Seção 36.14 e a Seção 36.15 para obter mais informações.

Ao definir um operador autocomutativo, basta fazê-lo. Ao definir um par de operadores comutativos, a situação é um pouco mais complexa: como é que o primeiro a ser definido pode se referir ao outro, que ainda não se encontra definido? Existem três soluções para este problema:

  • Uma maneira é omitir a cláusula COMMUTATOR no primeiro operador que for definido e, em seguida, fornecer uma na definição do segundo operador. Como o PostgreSQL sabe que os operadores comutativos vêm em pares, ao encontrar a segunda definição ele retornará automaticamente e preencherá a cláusula COMMUTATOR ausente na primeira definição.

  • Outra maneira, mais direta, é simplesmente incluir cláusulas COMMUTATOR nas duas definições. Quando o PostgreSQL processa a primeira definição e percebe que COMMUTATOR se refere a um operador inexistente, o sistema cria uma entrada fictícia para este operador no catálogo do sistema. Esta entrada fictícia terá dados válidos apenas para o nome do operador, os tipos de operandos esquerdo e direito e o dono, já que isto é tudo o que o PostgreSQL pode deduzir neste momento. A primeira entrada do catálogo do operador terá uma ligação para esta entrada fictícia. Posteriormente, ao definir o segundo operador, o sistema irá atualizar a entrada fictícia com as informações adicionais da segunda definição. Se for tentado usar o operador fictício antes que ele seja preenchido, será recebida uma mensagem de erro.

  • Como alternativa, os dois operadores podem ser definidos sem cláusulas COMMUTATOR e, em seguida, poderá ser usado o comando ALTER OPERATOR para definir suas ligações de comutador. É suficiente usar o comando ALTER em qualquer um dos dois.

Nos três casos, é necessário ser o dono dos dois operadores para marcá-las como comutadores.

Podem ser definidos pares de operadores negadores usando os mesmos métodos que os pares de comutadores.

Não é possível especificar a precedência léxica do operador no comando CREATE OPERATOR, porque o comportamento de precedência do analisador sintático está definido de forma fixa. Veja Precedência dos operadores para obter detalhes sobre precedência.

As opções obsoletas SORT1, SORT2, LTCMP e GTCMP eram usadas anteriormente para especificar os nomes dos operadores de classificação associados a um operador com suporte a junção por mesclagem. Isto não é mais necessário, porque as informações sobre os operadores associados são encontradas observando as famílias de operador da Árvore-B. Se uma dessas opções for fornecida, ela será ignorada, exceto para definir implicitamente MERGES como verdade.

É usado o comando DROP OPERATOR para remover operadores definidos pelo usuário de um banco de dados. É usado o comando ALTER OPERATOR para modificar operadores em um banco de dados.

Exemplos

O comando a seguir define um novo operador, igualdade de área, para o tipo de dados box:

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

Conformidade

O comando CREATE OPERATOR é uma extensão do PostgreSQL. Não existe operador definido pelo usuário no padrão SQL.

Veja também

ALTER OPERATOR, CREATE OPERATOR CLASS, DROP OPERATOR