O operador específico a ser usado na chamada de operador é determinado pelo procedimento mostrado abaixo. Deve ser observado que este procedimento é afetado indiretamente pela precedência dos operadores envolvidos. Veja a Seção 4.1.6 para obter mais informações.
Resolução do tipo em operando
pg_operator
os operadores a serem considerados. Se for utilizado um nome de operador não qualificado (o caso usual), os operadores a serem considerados são aqueles com nome e número de argumentos corretos, visíveis no caminho de procura corrente (veja a
Seção 5.8.3
). Se for utilizado um nome de operador qualificado, somente são considerados os operadores no esquema especificado.
Seguem alguns exemplos.
Exemplo 10-1. Resolução do tipo em operador de exponenciação
Existe apenas um operador de exponenciação definido no catálogo, e recebe argumentos do tipo double precision. O rastreador atribui o tipo inicial integer aos os dois argumentos desta expressão de consulta:
=> SELECT 2 ^ 3 AS "exp"; exp ----- 8 (1 linha)
Portanto, o analisador faz uma conversão de tipo nos dois operandos e a consulta fica equivalente a
=> SELECT CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "exp";
Exemplo 10-2. Resolução do tipo em operador de concatenação de cadeia de caracteres
Uma sintaxe estilo cadeia de caracteres é utilizada para trabalhar com tipos cadeias de caracteres, assim como para trabalhar com tipos de extensão complexa. Cadeias de caracteres de tipo não especificado se correspondem com praticamente todos os operadores candidatos.
Um exemplo com um argumento não especificado:
=> SELECT text 'abc' || 'def' AS "texto e desconhecido"; texto e desconhecido ---------------------- abcdef (1 linha)
Neste caso o analisador procura pela existência de algum operador recebendo o tipo text nos dois argumentos. Uma vez que existe, assume que o segundo argumento deve ser interpretado como sendo do tipo text.
Concatenação de tipos não especificados:
=> SELECT 'abc' || 'def' AS "não especificado"; não especificado ------------------ abcdef (1 linha)
Neste caso não existe nenhuma pista inicial do tipo a ser usado, porque não foi especificado nenhum tipo na consulta. Portanto, o analisador procura todos os operadores candidatos, e descobre que existem candidatos aceitando tanto cadeia de caracteres quanto cadeia de bits como entrada. Como a categoria cadeia de caracteres é a preferida quando está disponível, esta categoria é selecionada e, depois, é usado o tipo preferido para cadeia de caracteres, text, como o tipo específico para solucionar os literais de tipo desconhecido.
Exemplo 10-3. Resolução do tipo em operador de valor absoluto e fatorial
O catálogo de operadores do PostgreSQL possui várias entradas para o operador de prefixo @, todas implementando operações de valor absoluto para vários tipos de dado numéricos. Uma destas entradas é para o tipo float8, que é o tipo preferido da categoria numérica. Portanto, o PostgreSQL usa esta entrada quando na presença de uma entrada não numérica:
=> SELECT @ '-4.5' AS "abs"; abs ----- 4.5 (1 linha)
Aqui o sistema realiza uma conversão implícita de text para float8 antes de aplicar o operador escolhido. Pode ser verificado que foi utilizado float8, e não algum outro tipo, escrevendo-se:
=> SELECT @ '-4.5e500' AS "abs"; ERRO: "-4.5e500" está fora da faixa para o tipo double precision
Por outro lado, o operador de sufixo ! (fatorial) é definido apenas para tipos de dado inteiros, e não para float8. Portanto, se tentarmos algo semelhante usando o !, resulta em:
=> SELECT '20' ! AS "fatorial"; ERRO: operador não é único: "unknown" ! DICA: Não foi possível escolher um operador candidato melhor. Pode ser necessário adicionar uma conversão de tipo explícita.
Isto acontece porque o sistema não pode decidir qual dos vários operadores ! possíveis deve ser o preferido. Pode ser dada uma ajuda usando uma conversão explícita:
=> SELECT CAST('20' AS int8) ! AS "fatorial"; fatorial --------------------- 2432902008176640000 (1 linha)