Det är inte en bugg, det är en funktion... Det finns två punkter här.
-
Ersättning av "nu"
Låt oss ta en titt i dokumentationen (Datum /Tidsfunktioner och operatörer ):
Så
'now'
konverteras till en tidsstämpel vid analystid. -
Förberedda uttalanden
Okej, men vad betyder det när det gäller funktioner? Det är lätt att visa att en funktion tolkas varje gång du anropar den:
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)
I det här exemplet
'now'
beter sig som du förväntat dig.Vad är skillnaden? Din funktion använder SQL-satser och test() gör det inte. Låt oss titta på dokumentationen igen (PL/ pgSQL Plan Caching ):
Och här (Förbered uttalande ):
Därav
'now'
konverterades till en tidsstämpel när förberedd sats tolkades. Låt oss visa detta genom att skapa en förberedd sats utanför en funktion: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)
Det var vad som hände. 'now'
konverterades till en tidsstämpel en gång (när förberedd sats tolkades), och now()
ringde två gånger.