Não é um bug, é um recurso... Há dois pontos aqui.
-
Substituição de 'agora'
Vamos dar uma olhada na documentação (Data /Funções e operadores de tempo ):
Então'now'
é convertido em um carimbo de data/hora no momento da análise.
-
Declarações preparadas
Ok, mas o que isso significa em relação às funções? É fácil demonstrar que uma função é interpretada cada vez que você a chama:
t=# create function test() returns timestamp as $$ begin return 'now'; end; $$ language plpgsql; CREATE FUNCTION t=# select test(); test ---------------------------- 2015-12-11 11:14:43.479809 (1 row) t=# select test(); test ---------------------------- 2015-12-11 11:14:47.350266 (1 row)
Neste exemplo'now'
se comporta como você esperava.
Qual é a diferença? Sua função usa instruções SQL e test() não. Vamos examinar a documentação novamente (PL/ Cache de plano pgSQL ):
E aqui (Preparar Declaração ):
Portanto,'now'
foi convertido em um carimbo de data/hora quando a instrução preparada foi analisada. Vamos demonstrar isso criando uma instrução preparada fora de uma função:
t=# prepare s(integer) as UPDATE test_date_bug SET date2 = 'now' WHERE id = $1; PREPARE t=# execute s(1); UPDATE 1 t=# execute s(2); UPDATE 1 t=# select * from test_date_bug; id | date1 | date2 ----+-------------------------------+------------------------------- 3 | 2015-12-11 11:01:38.491656+03 | infinity 1 | 2015-12-11 11:01:37.91818+03 | 2015-12-11 11:40:44.339623+03 2 | 2015-12-11 11:01:37.931056+03 | 2015-12-11 11:40:44.339623+03 (3 rows)
Isso é o que aconteceu.
'now'
foi convertido para um timestamp uma vez (quando a instrução preparada foi analisada) e now()
foi chamado duas vezes.