Обсуждение: getting at the actual int4 value of an abstime

Поиск
Список
Период
Сортировка

getting at the actual int4 value of an abstime

От
jim@reptiles.org (Jim Mercer)
Дата:
i have a table which uses an abstime to store a time/date.

the data originates as unix time_t, which i convert to a string when inserting
the data into the table.

i do select's from the table with WHERE clauses that use the abstime stuff.

i want to get the results of a select as unix time_t, without having to use
the expensive mktime()/strptime() unix C calls.

is there a way to get the int4 value that postgres is storing raw for
abstime?

i'm working in C with libpq.

--
[ Jim Mercer    Reptilian Research      jim@reptiles.org   +1 416 410-5633 ]
[ The telephone, for those of you who  have forgotten, was a commonly used ]
[ communications technology in the days before electronic mail.            ]
[ They're still easy to find in most large cities. -- Nathaniel Borenstein ]

Re: [HACKERS] getting at the actual int4 value of an abstime

От
"Ross J. Reedstrom"
Дата:
On Tue, Aug 17, 1999 at 06:23:29PM -0400, Jim Mercer wrote:
>
> i have a table which uses an abstime to store a time/date.
>
> the data originates as unix time_t, which i convert to a string when inserting
> the data into the table.
>
> i do select's from the table with WHERE clauses that use the abstime stuff.
>
> i want to get the results of a select as unix time_t, without having to use
> the expensive mktime()/strptime() unix C calls.
>
> is there a way to get the int4 value that postgres is storing raw for
> abstime?

test=> create table timetest(timefield abstime);
CREATE
test=> select abstime_finite(timefield) from timetest;
abstime_finite
--------------
(0 rows)

test=> insert into timetest values (now());
INSERT 518323 1
test=> insert into timetest values (now());
INSERT 518324 1
test=> insert into timetest values (now());
INSERT 518325 1
test=> select abstime_finite(timefield) from timetest;
abstime_finite
--------------
t
t
t
(3 rows)

test=> select timefield from timetest;
timefield
----------------------------
Tue Aug 17 18:13:23 1999 CDT
Tue Aug 17 18:13:24 1999 CDT
Tue Aug 17 18:13:25 1999 CDT
(3 rows)

test=> select timefield::int4 from timetest;
?column?
----------------------------
Tue Aug 17 18:13:23 1999 CDT
Tue Aug 17 18:13:24 1999 CDT
Tue Aug 17 18:13:25 1999 CDT
(3 rows)

Hmm, this looks like a bug. I'm guessing we're storing and int8, and the
conversion fails, so falls back to the default text output?

test=> select timefield::int8 from timetest;
     int8
---------
934931603
934931604
934931605
(3 rows)

test=> select timefield::float from timetest;
   float8
---------
934931603
934931604
934931605
(3 rows)

test=> select timefield::numeric from timetest;
  numeric
---------
934931603
934931604
934931605
(3 rows)

test=>

What version of PostgreSQL, BTW? This is 6.5: int8 and numeric support got a
lot better vs. 6.4

Ross

--
Ross J. Reedstrom, Ph.D., <reedstrm@rice.edu>
NSBRI Research Scientist/Programmer
Computer and Information Technology Institute
Rice University, 6100 S. Main St.,  Houston, TX 77005

Re: [HACKERS] getting at the actual int4 value of an abstime

От
Thomas Lockhart
Дата:
> > i have a table which uses an abstime to store a time/date.
> > the data originates as unix time_t
> > i want to get the results of a select as unix time_t, without having
> > to use the expensive mktime()/strptime() unix C calls.
> > is there a way to get the int4 value that postgres is storing raw
> > for abstime?

postgres=> select date_part('epoch', timefield) from timetest;
date_part
---------
934957840
(1 rows)

> test=> select timefield::int4 from timetest;
> ?column?
> ----------------------------
> Tue Aug 17 18:13:23 1999 CDT
> Hmm, this looks like a bug. I'm guessing we're storing and int8, and the
> conversion fails, so falls back to the default text output?

Probably not. Abstime is internally stored as 4 bytes, roughly the
same as int4, and so Postgres is swallowing the conversion since it
thinks they are equivalent. But the output conversion is not
equivalent.

> test=> select timefield::int8 from timetest;
>      int8
> ---------
> 934931603
> What version of PostgreSQL, BTW? This is 6.5: int8 and numeric support got a
> lot better vs. 6.4

Trying to force a conversion to some other data type works, since the
conversion isn't swallowed by Postgres. The int4 behavior should count
as a bug...

                  - Thomas

--
Thomas Lockhart                lockhart@alumni.caltech.edu
South Pasadena, California

Re: [HACKERS] getting at the actual int4 value of an abstime

От
jim@reptiles.org (Jim Mercer)
Дата:
> test=> select timefield::int8 from timetest;
>      int8
> ---------
> 934931603
> 934931604
> 934931605
> (3 rows)

hmmm, as you did, i tried timefield::int4, and got the same results.
i hadn't tried timefield::int8.

i suspect this would be more efficient than date_part('epoch', timefield).

> What version of PostgreSQL, BTW? This is 6.5: int8 and numeric support got a
> lot better vs. 6.4

i am using 6.5, soon gonna upgrade to 6.5.1.

thanx, this will make my code much more efficient.

also, is there a reverse to this?

ie.  how does one inject unix time_t data into an abstime field.

i currently pass my raw data through a filter, which converts it
to 'yyyy-mm-dd HH:MM:SS'.

then i bring it in using: "COPY tb USING STDIN;"

it would be nice if i could do a batch of:
"INSERT INTO tb (time_t, data1, date2) VALUES (934931604, 'aa', 'bb');"

--
[ Jim Mercer    Reptilian Research      jim@reptiles.org   +1 416 410-5633 ]
[ The telephone, for those of you who  have forgotten, was a commonly used ]
[ communications technology in the days before electronic mail.            ]
[ They're still easy to find in most large cities. -- Nathaniel Borenstein ]

Re: [HACKERS] getting at the actual int4 value of an abstime

От
Tom Lane
Дата:
jim@reptiles.org (Jim Mercer) writes:
> [ concern about speed of converting datetime values to/from text for
>   Postgres ]

FWIW, I used to be really concerned about that too, because my
applications do lots of storage and retrieval of datetimes.
Then one day I did some profiling, and found that the datetime
conversion code was down in the noise.  Now I don't worry so much.

It *would* be nice though if there were some reasonably cheap documented
conversions between datetime and a standard Unix time_t displayed as a
number.  Not so much because of speed, as because there are all kinds
of ways to get the conversion wrong on the client side --- messing up
the timezone and not coping with all the Postgres datestyles are two
easy ways to muff it.

BTW, I believe Thomas is threatening to replace all the datetime-like
types with what is currently called datetime (ie, a float8 measuring
seconds with epoch 1/1/2000), so relying on the internal representation
of abstime would be a bad idea...

            regards, tom lane

Re: [HACKERS] getting at the actual int4 value of an abstime

От
Tom Lane
Дата:
Thomas Lockhart <lockhart@alumni.caltech.edu> writes:
>>>> i want to get the results of a select as unix time_t, without having
>>>> to use the expensive mktime()/strptime() unix C calls.
>>>> is there a way to get the int4 value that postgres is storing raw
>>>> for abstime?

> postgres=> select date_part('epoch', timefield) from timetest;
> date_part
> ---------
> 934957840
> (1 rows)

BTW, while rooting around in contrib/ I noticed that contrib/unixdate
has an efficient way of going the other direction: just apply the
conversion from abstime with a type cheat.  The coding is obsolete,
but updated to 6.5, it works fine:

regression=> CREATE FUNCTION datetime(int4) RETURNS datetime
regression-> AS 'abstime_datetime' LANGUAGE 'internal';
CREATE
regression=> select datetime(935779244);
datetime
----------------------------
Fri Aug 27 14:40:44 1999 EDT
(1 row)
regression=> select date_part('epoch',
regression-> 'Fri Aug 27 14:40:44 1999 EDT'::datetime);
date_part
---------
935779244
(1 row)

Nifty.  I wonder whether we shouldn't move this contrib feature into the
standard system for 6.6?  Perhaps with a less generic name, such as
epoch2datetime() --- otherwise the parser will think that it can use the
function as an automatic int4->datetime type conversion, which is probably
Not a Good Idea.  But having both conversion directions would sure make
life simpler and less error-prone for client apps that need to translate
datetimes to and from time_t.

            regards, tom lane

Re: [HACKERS] getting at the actual int4 value of an abstime

От
jim@reptiles.org (Jim Mercer)
Дата:
> BTW, while rooting around in contrib/ I noticed that contrib/unixdate
> has an efficient way of going the other direction: just apply the
> conversion from abstime with a type cheat.  The coding is obsolete,
> but updated to 6.5, it works fine:

i saw it there, but couldn't get it to work.

this looks like what i need.

--
[ Jim Mercer    Reptilian Research      jim@reptiles.org   +1 416 410-5633 ]
[ The telephone, for those of you who  have forgotten, was a commonly used ]
[ communications technology in the days before electronic mail.            ]
[ They're still easy to find in most large cities. -- Nathaniel Borenstein ]

Re: [HACKERS] getting at the actual int4 value of an abstime

От
José Soares
Дата:
You don't need to create such function it works already on v6.5:

prova=> select date_part('epoch', current_date);
date_part
---------
935964000
(1 row)

prova=> select datetime(935964000);
datetime
---------------------------
30/08/1999 00:00:00.00 CEST
(1 row)

prova=> select date_part('epoch','30/08/1999 00:00:00.00 CEST'::datetime);
date_part
---------
935964000
(1 row)

José

Tom Lane ha scritto:

> Thomas Lockhart <lockhart@alumni.caltech.edu> writes:
> >>>> i want to get the results of a select as unix time_t, without having
> >>>> to use the expensive mktime()/strptime() unix C calls.
> >>>> is there a way to get the int4 value that postgres is storing raw
> >>>> for abstime?
>
> > postgres=> select date_part('epoch', timefield) from timetest;
> > date_part
> > ---------
> > 934957840
> > (1 rows)
>
> BTW, while rooting around in contrib/ I noticed that contrib/unixdate
> has an efficient way of going the other direction: just apply the
> conversion from abstime with a type cheat.  The coding is obsolete,
> but updated to 6.5, it works fine:
>
> regression=> CREATE FUNCTION datetime(int4) RETURNS datetime
> regression-> AS 'abstime_datetime' LANGUAGE 'internal';
> CREATE
> regression=> select datetime(935779244);
> datetime
> ----------------------------
> Fri Aug 27 14:40:44 1999 EDT
> (1 row)
> regression=> select date_part('epoch',
> regression-> 'Fri Aug 27 14:40:44 1999 EDT'::datetime);
> date_part
> ---------
> 935779244
> (1 row)
>
> Nifty.  I wonder whether we shouldn't move this contrib feature into the
> standard system for 6.6?  Perhaps with a less generic name, such as
> epoch2datetime() --- otherwise the parser will think that it can use the
> function as an automatic int4->datetime type conversion, which is probably
> Not a Good Idea.  But having both conversion directions would sure make
> life simpler and less error-prone for client apps that need to translate
> datetimes to and from time_t.
>
>                         regards, tom lane
>
> ************