PostgreSQL - CAST vs :: operador na função da tabela LATERAL
Enquanto eu posso
SELECT elem[1], elem[2]
FROM ( VALUES ('1,2'::TEXT) ) AS q(arr),
LATERAL CAST(String_To_Array(q.arr, ',') AS INT[]) AS elem
;
usando uma chamada explícita para CAST
, eu não posso
SELECT elem[1], elem[2]
FROM ( VALUES ('1,2'::TEXT) ) AS q(arr),
LATERAL String_To_Array(q.arr, ',')::INT[] AS elem
;
usando o ::
operador de chamada implicitamente :
ERROR: erro de sintaxe em ou próximo a "::"
Um outro local em que um explícito CAST
é necessário:
CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );
Duvido que haja uma razão sintática, por exemplo, usar parênteses adicionais - que está incorreta aqui.
A chamada de função explícita é simplesmente necessária neste ponto como parte da implementação de baixo nível? Ou segue alguma regra de linguagem?
Respostas
Excelentes exemplos de casos extremos. Ambas as variantes de sintaxe são "conversões de tipo explícitas", fazendo exatamente o mesmo. Acontece que alguns locais especiais no código SQL permitem apenas a notação funcional para evitar ambigüidades.
Quanto à sua segunda observação:
Um outro local em que um explícito
CAST
é necessário:CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );
A sintaxe abreviada pode realmente ser usada aqui - com um conjunto adicional de parênteses para torná-la inequívoca:
CREATE INDEX ON ... ((<straw>::<gold>));
db <> fiddle aqui
E qualquer variante de sintaxe corresponde à outra expressão nas consultas também. Vejo:
- Podemos criar um índice para chave / valor do tipo de dados JSONB?
- Como criar um índice em uma propriedade json inteira no postgres
- Como dividir o Datetime em 2 colunas para o esquema de reserva do restaurante?
(Existem maneiras mais eficientes de fazer o que seu primeiro exemplo faz, mas isso provavelmente não vem ao caso.)
É um pouco estranho, sim, mas a gramática só aceitará algo sintaticamente semelhante a uma chamada de função em uma expressão function-in-FROM.
Portanto, esse é realmente um truque que você pode usar se quiser uma expressão arbitrária em uma FROM
cláusula: envolva-a com uma CAST
expressão desnecessária .
O PostgreSQL tratará alegremente qualquer coisa que se pareça com uma função como uma função de tabela em tal contexto.