Ini bukan bug, ini fitur... Ada dua poin di sini.
-
Pergantian 'sekarang'
Mari kita lihat dokumentasinya (Tanggal /Fungsi dan Operator Waktu ):
Jadi
'now'
dikonversi menjadi stempel waktu pada waktu penguraian. -
Pernyataan yang disiapkan
Oke, tapi apa artinya dalam kaitannya dengan fungsi? Sangat mudah untuk menunjukkan bahwa suatu fungsi ditafsirkan setiap kali Anda memanggilnya:
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)
Dalam contoh ini
'now'
berperilaku seperti yang Anda harapkan.Apa bedanya? Fungsi Anda menggunakan pernyataan SQL, dan test() tidak. Mari kita lihat dokumentasi lagi (PL/ Caching Paket pgSQL ):
Dan di sini (Siapkan Pernyataan ):
Oleh karena itu
'now'
dikonversi menjadi stempel waktu ketika pernyataan yang disiapkan diuraikan. Mari kita tunjukkan ini dengan membuat pernyataan yang disiapkan di luar fungsi: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)
Itulah yang terjadi. 'now'
dikonversi ke stempel waktu satu kali (ketika pernyataan yang disiapkan diuraikan), dan now()
dipanggil dua kali.