Re: BUG #2056: to_char no long takes time as input?

Lists: pgsql-bugspgsql-patches
From: "Nick Addington" <adding(at)math(dot)wisc(dot)edu>
To: pgsql-bugs(at)postgresql(dot)org
Subject: BUG #2056: to_char no long takes time as input?
Date: 2005-11-20 07:53:50
Message-ID: 20051120075350.5FEDCF0B25@svr2.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-patches


The following bug has been logged online:

Bug reference: 2056
Logged by: Nick Addington
Email address: adding(at)math(dot)wisc(dot)edu
PostgreSQL version: 8.1.0
Operating system: aix
Description: to_char no long takes time as input?
Details:

The following code works in 8.0.4 but fails in 8.1.0:

select to_char('1:00 pm'::time,'HH:MM AM');

8.1.0 gives this is the error message:
ERROR: invalid format specification for an interval value
HINT: Intervals are not tied to specific calendar dates.

I saw some discussion on the -hackers list about deprecating
to_char(interval, text), but do you really want to chuck to_char(time,
text)? That's a useful function. Or at least, I was using it...

Please advise,
Nick Addington


From: Michael Fuhr <mike(at)fuhr(dot)org>
To: Nick Addington <adding(at)math(dot)wisc(dot)edu>
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #2056: to_char no long takes time as input?
Date: 2005-11-20 09:07:14
Message-ID: 20051120090714.GA32592@winnie.fuhr.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-patches

On Sun, Nov 20, 2005 at 07:53:50AM +0000, Nick Addington wrote:
> The following code works in 8.0.4 but fails in 8.1.0:
>
> select to_char('1:00 pm'::time,'HH:MM AM');
>
> 8.1.0 gives this is the error message:
> ERROR: invalid format specification for an interval value
> HINT: Intervals are not tied to specific calendar dates.
>
> I saw some discussion on the -hackers list about deprecating
> to_char(interval, text), but do you really want to chuck to_char(time,
> text)? That's a useful function. Or at least, I was using it...

to_char(time,text) doesn't exist, at least not in 7.3 and later --
you can see that with "\df to_char" in psql. If you set debug_print_parse
to on and set client_min_messages to debug1, you'll see that the
function being called is funcid 1768, which is

test=> select 1768::regprocedure;
regprocedure
------------------------
to_char(interval,text)
(1 row)

You'll also see that this function's first argument is a function
expression with funcid 1370, which is

test=> select 1370::regprocedure;
regprocedure
------------------------------------
"interval"(time without time zone)
(1 row)

So the time value is first converted to an interval and then passed
to to_char(interval,text).

test=> select "interval"('1:00 pm'::time);
interval
----------
13:00:00
(1 row)

test=> select to_char('13:00:00'::interval,'HH:MM AM');
ERROR: invalid format specification for an interval value
HINT: Intervals are not tied to specific calendar dates.

This looks like the commit that changed the behavior in 8.1 (the
hint was added later):

http://archives.postgresql.org/pgsql-committers/2005-08/msg00200.php

--
Michael Fuhr


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Nick Addington" <adding(at)math(dot)wisc(dot)edu>
Cc: pgsql-bugs(at)postgresql(dot)org, Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
Subject: Re: BUG #2056: to_char no long takes time as input?
Date: 2005-11-20 16:59:47
Message-ID: 28941.1132505987@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-patches

"Nick Addington" <adding(at)math(dot)wisc(dot)edu> writes:
> The following code works in 8.0.4 but fails in 8.1.0:
> select to_char('1:00 pm'::time,'HH:MM AM');

I'm inclined to think that disallowing AM/PM for intervals was a mistake
--- if we allow both HH and HH24 (which we do) then the various flavors
of AM/PM seem reasonable to allow as well.

Bruce, did you have a specific rationale for that?

I notice the code now specifically forces HH to be treated as HH24 in
the interval case, which was not so before 8.1; we would need to revert
that change as well to continue supporting TIME cases reasonably.

regards, tom lane


From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Nick Addington <adding(at)math(dot)wisc(dot)edu>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #2056: to_char no long takes time as input?
Date: 2005-11-23 21:04:29
Message-ID: 200511232104.jANL4Tq12184@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-patches

Tom Lane wrote:
> "Nick Addington" <adding(at)math(dot)wisc(dot)edu> writes:
> > The following code works in 8.0.4 but fails in 8.1.0:
> > select to_char('1:00 pm'::time,'HH:MM AM');
>
> I'm inclined to think that disallowing AM/PM for intervals was a mistake
> --- if we allow both HH and HH24 (which we do) then the various flavors
> of AM/PM seem reasonable to allow as well.
>
> Bruce, did you have a specific rationale for that?
>
> I notice the code now specifically forces HH to be treated as HH24 in
> the interval case, which was not so before 8.1; we would need to revert
> that change as well to continue supporting TIME cases reasonably.

When I coded it I was thinking it doesn't make sense to allow "AM"/"PM" for
something like "5 hours". I disallowed anything that tied to a specific
timestamp value, even BC/AD.

I didn't realize "time" was used as input to to_char() as an interval.
I can see "time" as anchoring to midnight and we could then allow AM/PM.
I see your issue with HH/HH24, but I wanted this to work:

test=> select to_char('14 hours'::interval, 'HH');
to_char
---------
14
(1 row)

With the HH/HH24 change that is going to return 2. Do interval folks
know they would have to use HH24 for intervals? It doesn't seem 100%
clear, but I suppose we could just add a documentation about it, because
consider this:

test=> select to_char('44 hours'::interval, 'HH');
to_char
---------
44
(1 row)

With "HH" changed that would return 32. Ewe. Here is the formatting.c
code:

if (is_interval)
sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_hour);
else
sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2,
tm->tm_hour == 0 ? 12 :
tm->tm_hour < 13 ? tm->tm_hour : tm->tm_hour - 12);

Should we subtract 12 only if the time is < 24. That also seems
strange. Also, a zero hour interval to HH would return 12, not 0.

It also seems strange to use HH24 for a value that might be greater than
24 (hours), while 'time' can not.

Anyway, I am thinking the easiest solution is to allow 'time' work
easily with HH, and to document that HH24 needs to be used for
intervals.

If this is what we want, I can make the change.

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
Cc: Nick Addington <adding(at)math(dot)wisc(dot)edu>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #2056: to_char no long takes time as input?
Date: 2005-11-23 21:22:34
Message-ID: 26860.1132780954@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-patches

Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> I see your issue with HH/HH24, but I wanted this to work:

> test=> select to_char('14 hours'::interval, 'HH');
> to_char
> ---------
> 14
> (1 row)

> With the HH/HH24 change that is going to return 2. Do interval folks
> know they would have to use HH24 for intervals?

Dunno if they know it, but they always had to do it that way before 8.1,
so it's not a change to require it. I get this in everything back to
7.2:

regression=# select to_char('14 hours'::interval, 'HH');
to_char
---------
02
(1 row)

regression=# select to_char('14 hours'::interval, 'HH24');
to_char
---------
14
(1 row)

and I don't see anything especially wrong with that behavior, as long as
it's documented.

> Should we subtract 12 only if the time is < 24. That also seems
> strange. Also, a zero hour interval to HH would return 12, not 0.

Offhand I'd vote for making the HH code use a "mod 12" calculation,
and making AM/PM depend on the value "mod 24". This gives at least a
slightly sane behavior for intervals > 24 hours.

regards, tom lane


From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Nick Addington <adding(at)math(dot)wisc(dot)edu>, PostgreSQL-patches <pgsql-patches(at)postgresql(dot)org>
Subject: Re: [BUGS] BUG #2056: to_char no long takes time as input?
Date: 2005-12-02 04:01:01
Message-ID: 200512020401.jB2411917608@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-patches


Here is a patch that allows HH and HH12 to be used with interval, and
hence time. I added documentation to warn users that using those with
intervals are mapped to single-day values.

I will soon apply this to HEAD and 8.1.X.

---------------------------------------------------------------------------

Tom Lane wrote:
> Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> > I see your issue with HH/HH24, but I wanted this to work:
>
> > test=> select to_char('14 hours'::interval, 'HH');
> > to_char
> > ---------
> > 14
> > (1 row)
>
> > With the HH/HH24 change that is going to return 2. Do interval folks
> > know they would have to use HH24 for intervals?
>
> Dunno if they know it, but they always had to do it that way before 8.1,
> so it's not a change to require it. I get this in everything back to
> 7.2:
>
> regression=# select to_char('14 hours'::interval, 'HH');
> to_char
> ---------
> 02
> (1 row)
>
> regression=# select to_char('14 hours'::interval, 'HH24');
> to_char
> ---------
> 14
> (1 row)
>
> and I don't see anything especially wrong with that behavior, as long as
> it's documented.
>
> > Should we subtract 12 only if the time is < 24. That also seems
> > strange. Also, a zero hour interval to HH would return 12, not 0.
>
> Offhand I'd vote for making the HH code use a "mod 12" calculation,
> and making AM/PM depend on the value "mod 24". This gives at least a
> slightly sane behavior for intervals > 24 hours.
>
> regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Have you searched our list archives?
>
> http://archives.postgresql.org
>

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

Attachment Content-Type Size
unknown_filename text/plain 4.1 KB

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Nick Addington <adding(at)math(dot)wisc(dot)edu>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #2056: to_char no long takes time as input?
Date: 2005-12-02 04:02:38
Message-ID: 200512020402.jB242cs17780@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-patches


Oh, one more thing. With the new patch I just posted, '0 hours' and
'HH' returns 12:

test=> select to_char('0 hours'::interval, 'HH');
to_char
---------
12
(1 row)

Of course HH24 works fine.

---------------------------------------------------------------------------

Tom Lane wrote:
> Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> > I see your issue with HH/HH24, but I wanted this to work:
>
> > test=> select to_char('14 hours'::interval, 'HH');
> > to_char
> > ---------
> > 14
> > (1 row)
>
> > With the HH/HH24 change that is going to return 2. Do interval folks
> > know they would have to use HH24 for intervals?
>
> Dunno if they know it, but they always had to do it that way before 8.1,
> so it's not a change to require it. I get this in everything back to
> 7.2:
>
> regression=# select to_char('14 hours'::interval, 'HH');
> to_char
> ---------
> 02
> (1 row)
>
> regression=# select to_char('14 hours'::interval, 'HH24');
> to_char
> ---------
> 14
> (1 row)
>
> and I don't see anything especially wrong with that behavior, as long as
> it's documented.
>
> > Should we subtract 12 only if the time is < 24. That also seems
> > strange. Also, a zero hour interval to HH would return 12, not 0.
>
> Offhand I'd vote for making the HH code use a "mod 12" calculation,
> and making AM/PM depend on the value "mod 24". This gives at least a
> slightly sane behavior for intervals > 24 hours.
>
> regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Have you searched our list archives?
>
> http://archives.postgresql.org
>

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
Cc: Nick Addington <adding(at)math(dot)wisc(dot)edu>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #2056: to_char no long takes time as input?
Date: 2005-12-02 04:06:50
Message-ID: 27565.1133496410@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-patches

Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> Oh, one more thing. With the new patch I just posted, '0 hours' and
> 'HH' returns 12:

> test=> select to_char('0 hours'::interval, 'HH');
> to_char
> ---------
> 12
> (1 row)

Yeah, it's done that in every release since 7.2. 8.1.0 is the only
release that thinks 00 is correct.

regards, tom lane


From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Nick Addington <adding(at)math(dot)wisc(dot)edu>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #2056: to_char no long takes time as input?
Date: 2005-12-03 16:46:11
Message-ID: 200512031646.jB3GkC223841@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-patches


Patch applied to HEAD and 8.1.X.

---------------------------------------------------------------------------

Tom Lane wrote:
> Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> > I see your issue with HH/HH24, but I wanted this to work:
>
> > test=> select to_char('14 hours'::interval, 'HH');
> > to_char
> > ---------
> > 14
> > (1 row)
>
> > With the HH/HH24 change that is going to return 2. Do interval folks
> > know they would have to use HH24 for intervals?
>
> Dunno if they know it, but they always had to do it that way before 8.1,
> so it's not a change to require it. I get this in everything back to
> 7.2:
>
> regression=# select to_char('14 hours'::interval, 'HH');
> to_char
> ---------
> 02
> (1 row)
>
> regression=# select to_char('14 hours'::interval, 'HH24');
> to_char
> ---------
> 14
> (1 row)
>
> and I don't see anything especially wrong with that behavior, as long as
> it's documented.
>
> > Should we subtract 12 only if the time is < 24. That also seems
> > strange. Also, a zero hour interval to HH would return 12, not 0.
>
> Offhand I'd vote for making the HH code use a "mod 12" calculation,
> and making AM/PM depend on the value "mod 24". This gives at least a
> slightly sane behavior for intervals > 24 hours.
>
> regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Have you searched our list archives?
>
> http://archives.postgresql.org
>

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073