CREATE OPERATOR

Name

CREATE OPERATOR  --  define um novo operador

Synopsis

CREATE OPERATOR nome ( PROCEDURE = nome_da_função
     [, LEFTARG = tipo_esquerdo
     ] [, RIGHTARG = tipo_direito ]
     [, COMMUTATOR = op_comutador ] [, NEGATOR = op_negador ]
     [, RESTRICT = proc_restr ] [, JOIN = proc_juncao ]
     [, HASHES ] [, SORT1 = op_ord_esq ] [, SORT2 = op_ord_dir ] )
  

Entradas

nome

O operador a ser definido. Veja abaixo os caracteres permitidos.

nome_da_função

A função utilizada para implementar este operador.

tipo_esquerdo

O tipo do argumento do lado esquerdo do operador, se houver. Esta opção é omitida em um operador unário esquerdo.

tipo_direito

O tipo do argumento do lado direito do operador, se houver. Esta opção é omitida em um operador unário direito.

op_comutador

O comutador deste operador.

op_negador

O negador deste operador.

proc_restr

A função estimadora de seletividade de restrição para este operador.

proc_juncao

A função estimadora de seletividade de junção para este operador.

HASHES

Indica que este operador pode suportar uma junção por hash.

op_ord_esq

Se este operador pode suportar uma junção por mesclagem, o operador que ordena o tipo de dado do lado esquerdo deste operador.

op_ord_dir

Se este operador pode suportar uma junção por mesclagem, o operador que ordena o tipo de dado do lado direito deste operador.

Saídas

CREATE

Mensagem retornada se o operador for criado com sucesso.

Descrição

O comando CREATE OPERATOR define um novo operador nome. O usuário que define um operador se torna seu dono.

O operador nome é uma seqüência de até NAMEDATALEN-1 (31 por padrão) caracteres da seguinte lista:

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

Existem algumas restrições na escolha do nome:

Note: Ao se trabalhar com nomes de operadores que não sejam padrão SQL, usualmente é necessário usar espaços entre os operadores adjacentes para evitar ambigüidade. Por exemplo, definindo-se um operador unário esquerdo chamado @, não se pode escrever X*@Y; deve-se escrever X* @Y para garantir que o PostgreSQL leia dois nomes de operadores e não um.

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

Pelo menos um entre LEFTARG e RIGHTARG deve ser definido. Para operadores binários ambos devem ser definidos. Para operadores unários direito somente o LEFTARG deve ser definido, enquanto que para operadores unários esquerdo somente o RIGHTARG deve ser definido.

O procedimento nome_da_função deve ser previamente definido utilizando o comando CREATE FUNCTION, e deve estar definido para aceitar o número correto de argumentos (um ou dois) dos tipos indicados.

O operador comutador deve ser identificado, se existir, para que o PostgreSQL possa reverter a ordem dos operandos se desejar. Por exemplo, o operador area-menor-do-que, <<<, provavelmente teria o operador comutador area-maior-do-que, >>>. Com isso, o otimizador de consultas poderia livremente converter:

caixa '((0,0), (1,1))'  >>> minhas_caixas.descricao
   

em

minhas_caixas.descricao <<< caixa '((0,0), (1,1))'
   

Isto permite o código de execução sempre utilizar a última representação e simplifica um pouco o otimizador de consultas.

Analogamente, se existir um operador negador então este deve ser identificado. Suponha que exista um operador area-igual, ===, assim como um area-diferente, !==. A ligação negador permite ao otimizador de consultas simplificar

NOT minhas_caixas.descricao === caixa '((0,0), (1,1))'
   

para

minhas_caixas.descricao !== caixa '((0,0), (1,1))'
   

Se for fornecido o nome de um operador comutador, o PostgreSQL procura-o no catálogo. Se encontrá-lo, e este ainda não tiver um comutador próprio, então a entrada do comutador é atualizada para ter o novo operador criado como sendo o seu comutador. Aplica-se igualmente ao negador. Isto serve para permitir a definição de dois operadores que são o comutador ou o negador um do outro. O primeiro operador deve ser definido sem um comutador ou negador (conforme apropriado). Quando o segundo operador for definido, este nomeará o primeiro como seu comutador ou negador. O primeiro será atualizado como efeito colateral (A partir do PostgreSQL 6.5, isto também funciona para se ter apenas dois operadores referindo um ao outro).

As opções HASHES, SORT1 e SORT2 estão presentes para apoiar o otimizador de consultas na realização de junções. O PostgreSQL sempre pode avaliar uma junção (i.e., processar uma cláusula com duas variáveis tuplas separadas por um operador que retorna um booleano) por substituição interativa [WONG76]. Adicionalmente, o PostgreSQL pode usar um algoritmo junção-hash junto com as linhas de [SHAP86]; entretanto, necessita saber se esta estratégia é aplicável. O algoritmo atual de junção-hash é correto apenas para operadores que representam testes de igualdade; além disso, a igualdade do tipo de dado deve significar igualdade bit a bit da representação do tipo (Por exemplo, um tipo de dado que contém bits não utilizados, que não fazem diferença nos testes de igualdade, não pode utilizar junção-hash). O sinalizador HASHES indica ao otimizador de consultas que a junção-hash pode ser usada com segurança com este operador.

Analogamente, os dois operadores de ordenação indicam ao otimizador de consultas se mesclagem-ordenação é uma estratégia de junção utilizável e quais operadores devem ser usados para ordenar as duas classes de operando. Os operadores de ordenação somente devem ser fornecidos para um operador de igualdade, devendo fazer referência aos operadores menor-do-que para os tipos de dado da esquerda e da direita, respectivamente.

Se forem descobertas outras estratégias de junção consideradas práticas, o PostgreSQL mudará o otimizador e o sistema de execução para usá-las, demandando especificação adicional quando um operador for definido. Felizmente, a comunidade de pesquisa não inventa novas estratégias de junção freqüentemente, e a generalidade adicionada por estratégias de junção definidas pelo usuário não foram consideradas como valendo a complexidade envolvida.

As opções RESTRICT e JOIN ajudam o otimizador de consultas a estimar o tamanho dos resultados. Se uma cláusula da forma:

minhas_caixas.descricao <<< caixa '((0,0), (1,1))'
   

estiver presente na qualificação, então o PostgreSQL poderá ter que estimar a fração das instâncias de minhas_caixas que satisfazem a cláusula. A função proc_restr deve ser uma função registrada (o que significa ter sido definida usando o comando CREATE FUNCTION) que aceita argumentos do tipo de dado correto e que retorna um número de ponto flutuante. O otimizador de consultas simplesmente chama esta função, passando o parâmetro ((0,0), (1,1)) e multiplica o resultado pelo tamanho da relação para obter o número esperado de instâncias.

Analogamente, quando os dois operandos do operador contêm variáveis instâncias, o otimizador deve estimar o tamanho da junção resultante. A função proc_juncao retornará outro número de ponto flutuante que será multiplicado pelas cardinalidades das duas tabelas envolvidas para calcular o tamanho esperado do resultado.

A diferença entre a função

meu_procedimento_1 (minhas_caixas.descricao, caixa '((0,0), (1,1))')
   

e o operador

minhas_caixas.descricao === caixa '((0,0), (1,1))'
   

é que o PostgreSQL tenta otimizar operadores e pode decidir usar um índice para restringir o espaço de procura quando operadores estão envolvidos. Entretanto, não existe tentativa de otimizar funções, que são executadas pela força bruta. Mais ainda, as funções podem possuir qualquer número de argumentos, enquanto os operadores estão restritos a um ou dois.

Notas

Consulte o capítulo sobre operadores no Guia do Usuário do PostgreSQL para obter mais informações. Consulte o comando DROP OPERATOR para excluir do banco de dados um operador definido pelo usuário.

Utilização

O comando a seguir define o novo operador "area-igualdade" para o tipo de dado CAIXA:

CREATE OPERATOR === (
   LEFTARG = caixa,
   RIGHTARG = caixa,
   PROCEDURE = area_igual_procedimento,
   COMMUTATOR = ===,
   NEGATOR = !==,
   RESTRICT = area_restricao_procedimento,
   JOIN = area_juncao_procedimento,
   HASHES,
   SORT1 = <<<,
   SORT2 = >>>
);
  

Compatibilidade

SQL92

O comando CREATE OPERATOR é uma extensão do PostgreSQL à linguagem. Não existe o comando CREATE OPERATOR no SQL92.