Eu tenho um auxiliar que está gerando algum código para fazer atualizações em massa para mim e gera SQL que se parece com isso:
(Ambos os campos ativo e principal são do tipo boolean
)
UPDATE fields as t set "active" = new_values."active","core" = new_values."core"
FROM (values
(true,NULL,3419),
(false,NULL,3420)
) as new_values("active","core","id") WHERE new_values.id = t.id;
No entanto, ele falha com:
ERROR: column "core" is of type boolean but expression is of type text
Eu posso fazê-lo funcionar adicionando ::boolean
aos nulos, mas isso parece estranho, por que NULL é considerado do tipo TEXT
?
Além disso, é um pouco complicado de converter porque exigiria um pouco de retrabalho do código para saber para que tipo deve converter NULLs (a lista de colunas e valores está sendo gerada automaticamente a partir de uma matriz simples de objetos JSON) .
Por que isso é necessário e existe uma solução mais elegante que não exija que o código gerador saiba o tipo de NULLs?
Se for relevante, estou usando sequelize sobre Node.JS para fazer isso, mas também estou obtendo o mesmo resultado no cliente de linha de comando Postgres.
Esta é uma descoberta interessante. Normalmente, um NULL não tem tipo de dados assumido, como você pode ver aqui:
Isso muda quando uma
VALUES
tabela entra na imagem:Esse comportamento é descrito no código-fonte em https://doxygen.postgresql.org/parse__coerce_8c.html#l01373 :
(Sim, o código-fonte do PostgreSQL é relativamente fácil de entender e na maioria dos lugares, graças a excelentes comentários.)
A saída, no entanto, pode ser a seguinte. Digamos que você esteja sempre gerando
VALUES
que correspondam a todas as colunas de uma determinada tabela (veja a segunda nota abaixo para outros casos). Do seu exemplo, um pequeno truque poderia ajudar:Aqui você usa expressões de linha convertidas para o tipo da tabela e, em seguida, extrai-as de volta para uma tabela.
Com base no acima, seu
UPDATE
poderia parecerNotas:
Olhe para a coisa toda trabalhando em dbfiddle .