Ce n'est pas un bug, c'est une fonctionnalité... Il y a deux points ici.
-
Remplacement de 'maintenant'
Regardons la documentation (Date /Fonctions et opérateurs de temps ):
Donc
'now'
est converti en horodatage au moment de l'analyse. -
Relevés préparés
D'accord, mais qu'est-ce que cela signifie en ce qui concerne les fonctions ? Il est facile de démontrer qu'une fonction est interprétée à chaque fois que vous l'appelez :
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)
Dans cet exemple
'now'
se comporte comme prévu.Quelle est la différence? Votre fonction utilise des instructions SQL, contrairement à test(). Examinons à nouveau la documentation (PL/ Mise en cache du plan pgSQL ):
Et ici (Préparer la déclaration ):
D'où
'now'
a été converti en horodatage lorsque l'instruction préparée a été analysée. Démontrons cela en créant une instruction préparée en dehors d'une fonction :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)
C'est ce qui s'est passé. 'now'
a été converti en horodatage une fois (lorsque l'instruction préparée a été analysée) et now()
a été appelé deux fois.