Non è un bug, è una funzionalità... Ci sono due punti qui.
-
Sostituzione di 'ora'
Diamo un'occhiata alla documentazione (Data /Funzioni temporali e operatori ):
Quindi
'now'
viene convertito in un timestamp al momento dell'analisi. -
Dichiarazioni preparate
Va bene, ma cosa significa per quanto riguarda le funzioni? È facile dimostrare che una funzione viene interpretata ogni volta che la chiami:
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)
In questo esempio
'now'
si comporta come ti aspettavi.Qual è la differenza? La tua funzione usa le istruzioni SQL e test() no. Esaminiamo nuovamente la documentazione (PL/ pgSQL Pianifica la memorizzazione nella cache ):
E qui (Preparare la dichiarazione ):
Quindi
'now'
è stato convertito in un timestamp durante l'analisi dell'istruzione preparata. Dimostriamolo creando un'istruzione preparata al di fuori di una funzione: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)
Questo è quello che è successo. 'now'
è stato convertito in un timestamp una volta (quando l'istruzione preparata è stata analizzata) e now()
è stato chiamato due volte.