domingo, 5 de fevereiro de 2017

Erros comuns no PostgreSQL II - comparação entre timestamps

Um modo de resolver problema de comparação de datas do tipo timestamp with timezone no PostgreSQL 8.4.8

Estou trabalhando na conversão de um banco MySQL para PostgreSQL. Embora exista uma SQL ANSI, cada banco tem seu dialeto particular. Além disso, há os tipos de dados específicos de cada banco.

Bem, eu tive de passar um campo de data para o tipo timestamp with timezone do PostgreSQL, versão 8.4.8. E na aplicação que usa o banco existem algumas consultas que fazem comparações de data.

Bem, havia uma comparação assim: 'expires_at' > NOW(). O campo expires_at é do tipo timestamp with timezone e a função NOW retorna o dia de hoje como timestamp with timezone também. Então, a princípio, eu estava comparando limão com limão e deveria funcionar.

Mas na execução, o PostgreSQL chiava dizendo que havia uma entrada inválida e apontava o campo expires_at. Peguei a documentação do PostgreSQL, na parte de funções de data e hora, e tentei desvendar o problema. Parecia não ter sentido, pois eu estava comparando coisas iguais.

Consultei um colega antes de submeter essa dúvida a um fórum, para verificar se não era algo trivial e evitar ser massacrado pelos especialistas, fartos de responderem questões perdidas na milésima página de resultados das buscas. Bem, não desvendamos o mistério, mas encontramos uma solução alternativa:

age(expires_at,now()) > interval '1 day'

Quer dizer, em vez de comparar as datas diretamente, eu comparei o intervalo. Mas isso não parecia elegante.

Depois de pensar bastante na mensagem de erro original, fiz um teste. O delimitador do PostgreSQL é apóstrofo. Mas em um paradoxo, coloquei o campo expires_at entre aspas. E funcionou. Por que? Não sei, só sei que foi assim.

Solução:

"expires_at" > now()

Estou contando porque se alguém passar por um problema parecido, há uma solução. Solução, não explicação.

Nenhum comentário:

Postar um comentário