Na verdade, existem três perguntas que vou tentar responder.
-
Qual é o propósito deunknown
?
Este é o tipo de dados inicialmente atribuído a NULLs e literais de string em instruções SQL. Se tais literais foram atribuídos ao tipotext
imediatamente, seria difícil inferir o tipo correto.
Por exemplo, você quermyfunc('hello')
para invocarmyfunc(character varying)
, mas não há conversão de tipo implícito detext
paracharacter varying
(e causaria ambiguidade se você criasse um).
-
Por queSELECT null
retornar uma coluna do tipounknown
?
A resposta tradicional é:porque o usuário não especificou o tipo.
No entanto, esse comportamento tem sido problemático. Por exemplo, se você criar uma tabela como esta:
CREATE TABLE test AS SELECT 'hello';
você terminaria com uma coluna do tipounknown
, o que é indesejável e causará problemas mais adiante. O tipounknown
realmente não deve ser visível ao usuário, mas sim um detalhe de implementação.
Consequentemente, este commit mudou o comportamento do PostgreSQL v10 em:Agora qualquerunknown
s deixados em umSELECT
ouRETURNING
list são forçados atext
, e as tabelas não podem ser criadas com colunas do tipounknown
.
-
Por queSELECT NULL UNION SELECT 42
funciona, mas nãoSELECT NULL UNION SELECT NULL UNION SELECT 42
?
Isso se deve às regras de conversão de tipo .UNION
é associativo à esquerda, então a última consulta é interpretada como
(SELECT NULL UNION SELECT NULL) UNION SELECT 42;
Agora o primeiroUNION
resolve para o tipo de dadostext
por causa da regra 3:
Isso causa um erro ao tentar resolver o tipo para o segundoUNION
por causa da regra 4:
Por outro lado, na consulta
SELECT NULL UNION SELECT 42;
“NULL” tem o tipounknown
, e "42" tem o tipointeger
(o tipo escolhido para literais numéricos sem ponto decimal).
Regra 5
não se aplica aqui, porqueinteger
não é um tipo preferido na sua categoria (isso seriaoid
edouble precision
), então a regra 6 é usada:
Isso resulta em um tipo deinteger
.