Function parameter type precision modifiers ignored.
От | Mark Simonetti |
---|---|
Тема | Function parameter type precision modifiers ignored. |
Дата | |
Msg-id | 54D39E4A.9030600@opalsoftware.co.uk обсуждение исходный текст |
Ответы |
Re: Function parameter type precision modifiers ignored.
|
Список | pgsql-bugs |
Hi, I don't know if this is a bug as such, but the behaviour certainly confused me for a while : - Given the following PostgreSQL functions: CREATE OR REPLACE FUNCTION fn_dtm ( dtm timestamptz(0)) RETURNS void AS $$ BEGIN RAISE NOTICE 'fn: %, %', dtm, dtm::timestamptz(0); END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION fn_num ( num numeric(5, 2)) RETURNS void AS $$ BEGIN RAISE NOTICE 'num: %, %', num, num::numeric(5, 2); END; $$ LANGUAGE plpgsql; Would you expect the output of these functions to show the result as per the type declared in the function parameter? I was very surprised to find that the precision was retained and shown in the "NOTICE" despite the parameter type limiting the precision. Is this a bug or am I just thinking about it the wrong way? Here is the output: db=> SELECT fn_dtm(now()); NOTICE: fn: 2015-02-05 10:25:44.184+00, 2015-02-05 10:25:44+00 db=> SELECT fn_num(1.23456789); NOTICE: num: 1.23456789, 1.23 I am using PostgreSQL 9.3. CREATE OR REPLACE FUNCTION fn_dtm ( dtm timestamptz(0)) RETURNS void AS $$ BEGIN dtm = dtm::timestamptz(0); ----- CHANGE PRECISION RAISE NOTICE 'fn: %', dtm; END; $$ LANGUAGE plpgsql; Gives: db=> SELECT fn_dtm(now()); NOTICE: fn: 2015-02-05 10:38:38+00 I don't know if the behaviour is documented anywhere (sorry if I've missed it), but not knowing this really confused me for a good couple of hours. For fun here was the scenario : - 1) For my monitoring system I have a readings table. In my readings table I store the timestamp only to a 1 second precision (timestamptz(0)). 2) When a new "live" reading comes in, I use "now()" to get the timestamp. I then pass this to another function with the reading parameters, including a time argument (of type timestamptz(0)) which gets passed now()). Lets say now() is 2015-02-05 16:35:38.923. 3) The new reading gets stored in the database, and since the field type is timestamptz(0) it gets rounded up to (2015-02-05 16:35:39). 4) If the new reading indicates an alarm state, I do a pg_notify to send an event to my app which includes the passed in timestamp. Now I assumed because of the parameter type this would not include milliseconds, so naturally I ignore anything after the seconds when I parse the notification event.. So I end up with 2015-02-05 16:35:38. Spot the difference to the stored timestamp? 5) The application then periodically loads the readings in alarm from the database based on the events received. So I do SELECT ..... WHERE reading_dtm = '2015-02-05 16:35:38' etc. Obviously nothing is returned as the timestamp is out by one second (except where the original reading timestamp was not rounded up). I've fixed it by just doing p_reading_dtm = p_reading_dtm::timestamptz(0) at the start of my function. Seems odd though when the parameter type is already timestamptz(0). Regards, Mark. --
В списке pgsql-bugs по дате отправления: