No es un error, es una característica... Hay dos puntos aquí.
-
Sustitución de 'ahora'
Echemos un vistazo a la documentación (Date /Funciones de tiempo y operadores ):
Así que
'now'
se convierte en una marca de tiempo en el momento del análisis. -
Declaraciones preparadas
Bien, pero ¿qué significa con respecto a las funciones? Es fácil demostrar que una función se interpreta cada vez que la llamas:
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)
En este ejemplo
'now'
se comporta como esperabas.¿Cuál es la diferencia? Su función usa sentencias SQL y test() no. Veamos la documentación nuevamente (PL/ Almacenamiento en caché del plan pgSQL ):
Y aquí (Preparar Declaración ):
Por lo tanto
'now'
se convirtió en una marca de tiempo cuando se analizó la declaración preparada. Demostremos esto creando una declaración preparada fuera de una función: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)
Eso es lo que pasó. 'now'
se convirtió en una marca de tiempo una vez (cuando se analizó la declaración preparada) y now()
fue llamado dos veces.