Re: BUG #13812: 'now' acting differently than now() in function - Mailing list pgsql-bugs

From David G. Johnston
Subject Re: BUG #13812: 'now' acting differently than now() in function
Date
Msg-id CAKFQuwYBE-iZKiKP-gkzR8qEp=kdjWHO7SsgH4XHFJn6bmwAmw@mail.gmail.com
Whole thread Raw
In response to BUG #13812: 'now' acting differently than now() in function  (darin@darinhoward.com)
Responses Re: BUG #13812: 'now' acting differently than now() in function  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs
On Thu, Dec 10, 2015 at 12:52 PM, <darin@darinhoward.com> wrote:

> The following bug has been logged on the website:
>
> Bug reference:      13812
> Logged by:          Darin Howard
> Email address:      darin@darinhoward.com
> PostgreSQL version: 9.4.5
> Operating system:   Linux
> Description:
> =E2=80=8B[...]=E2=80=8B
>
> I would not expect the date2 on row 2 to be the same date2 as row 1.
>
> Replacing
>
>  UPDATE test_date_bug SET date2 =3D 'now' WHERE id =3D id_param;
> With
>
>  UPDATE test_date_bug SET date2 =3D now() WHERE id =3D id_param;
> Sets new date as I would expect:
>

*=E2=80=8BQuick answer: *'now' is a string literal that is resolved once an=
d
embedded (i.e., parsed) into the query for the life of the session due to
caching; now() is a function that gets executed each time the query is
executed.=E2=80=8B

*Additional considerations:*=E2=80=8B

=E2=80=8BI may be missing a nuance here, this could
maybe use better documentation surrounding implications, but the basic
answer is that 'now' is a string literal that ends up getting resolved at
parse time during the first invocation of the function and then its value
is cached and re-used during subsequent executions.  The "now()" volatile
function is instead left alone by the parser and instead is invoked during
each execution of the UPDATE.

I am going from memory here since I cannot locate the documentation that
points out this fact...

The same behavior is seen if you trying to use "now" and "now()" as part of
the column default (SQL functions that can be written without parens but
that can only be functions do not exhibit this behavior).  Using "now" you
end up getting the time the table was created instead of the time the row
was inserted;

CREATE TABLE now_test (id serial, tm timestamptz DEFAULT 'now');
INSERT INTO now_test DEFAULT VALUES;  --repeat manually
SELECT * FROM now_test; --all same values for tm

David J.

pgsql-bugs by date:

Previous
From: "David G. Johnston"
Date:
Subject: Re: BUG #13811: Default ordering colums
Next
From: Tom Lane
Date:
Subject: Re: BUG #13812: 'now' acting differently than now() in function