Обсуждение: cast not IMMUTABLE?

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

cast not IMMUTABLE?

От
Gaetano Mendola
Дата:
Hi all,
I have a table with ~ 3e+6 rows on it.

I do select on this table in this way:


(1) select * from user_logs where login_time::date = now()::date;


consider that login_time is a TIMESTAMPTZ with an index on it.

If I use the select in this way:

select * from user_logs where login_time = now();

the the index is used.

I'm trying to use define and index in order to help the query (1):


test# create index idx on user_logs ( (login_time::date) );
ERROR:  functions in index expression must be marked IMMUTABLE


why that cast is not considered IMMUTABLE ?


How can I define an index for the query (1) ?


Regards
Gaetano Mendola











Re: cast not IMMUTABLE?

От
Sam Barnett-Cormack
Дата:
On Fri, 7 May 2004, Gaetano Mendola wrote:

> Hi all,
> I have a table with ~ 3e+6 rows on it.
>
> I do select on this table in this way:
>
>
> (1) select * from user_logs where login_time::date = now()::date;
>
>
> consider that login_time is a TIMESTAMPTZ with an index on it.
>
> If I use the select in this way:
>
> select * from user_logs where login_time = now();
>
> the the index is used.
>
> I'm trying to use define and index in order to help the query (1):
>
>
> test# create index idx on user_logs ( (login_time::date) );
> ERROR:  functions in index expression must be marked IMMUTABLE
>
>
> why that cast is not considered IMMUTABLE ?
>
>
> How can I define an index for the query (1) ?

The way I have done such queries hs been to create functions, marked
immutable, that encapsulate the cast/non-immutable internal function, if
I know that it *is* really immutable, at least for my purposes, and use
a functional index.

--
Sam Barnett-Cormack
Software Developer                           |  Student of Physics & Maths
UK Mirror Service (http://www.mirror.ac.uk)  |  Lancaster University

Re: cast not IMMUTABLE?

От
Tom Lane
Дата:
Gaetano Mendola <mendola@bigfoot.com> writes:
> consider that login_time is a TIMESTAMPTZ with an index on it.
> test# create index idx on user_logs ( (login_time::date) );
> ERROR:  functions in index expression must be marked IMMUTABLE

> why that cast is not considered IMMUTABLE ?

Because it depends on your TimeZone setting.  Observe:

regression=# begin;
BEGIN
regression=# select now(), now()::date;
              now              |    now
-------------------------------+------------
 2004-05-06 20:40:16.038307-04 | 2004-05-06
(1 row)

regression=# set timezone to 'GMT';
SET
regression=# select now(), now()::date;
              now              |    now
-------------------------------+------------
 2004-05-07 00:40:16.038307+00 | 2004-05-07
(1 row)

now() didn't change, but now()::date did.


> How can I define an index for the query (1) ?

What behavior are you really after here?  You could change the column to
be timestamp without time zone (which would have an immutable conversion
to date), but if you want login_time to reflect some sort of absolute
reality then that's likely not the right answer.

Another possibility is to force the date conversion to occur with
respect to a particular time zone.  I was going to suggest something
like
    (login_time at time zone 'GMT')::date
but upon experimenting I see that that isn't considered immutable either
:-(.  Offhand I think this may be an oversight --- I can't see any reason
for the various flavors of AT TIME ZONE (a/k/a timezone() function)
not to be considered immutable.  (Hackers, any comments?)

            regards, tom lane

Re: cast not IMMUTABLE?

От
Stephan Szabo
Дата:
On Fri, 7 May 2004, Gaetano Mendola wrote:

> Hi all,
> I have a table with ~ 3e+6 rows on it.
>
> I do select on this table in this way:
>
>
> (1) select * from user_logs where login_time::date = now()::date;
>
>
> consider that login_time is a TIMESTAMPTZ with an index on it.
>
> If I use the select in this way:
>
> select * from user_logs where login_time = now();
>
> the the index is used.
>
> I'm trying to use define and index in order to help the query (1):
>
>
> test# create index idx on user_logs ( (login_time::date) );
> ERROR:  functions in index expression must be marked IMMUTABLE
>
>
> why that cast is not considered IMMUTABLE ?

I'd think the conversion of a timestamptz -> date would be dependent on
timezone which would make it not immutable.


Re: cast not IMMUTABLE?

От
Enrico Weigelt
Дата:
* Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> > why that cast is not considered IMMUTABLE ?
>
> Because it depends on your TimeZone setting.  Observe:

BTW: whats really the difference between timezone and
timezonetz ? I always used to use timestamp (w/o tz) and
thought timestamptz was just an question of presentation.


cu
--
---------------------------------------------------------------------
 Enrico Weigelt    ==   metux IT service

  phone:     +49 36207 519931         www:       http://www.metux.de/
  fax:       +49 36207 519932         email:     contact@metux.de
  cellphone: +49 174 7066481
---------------------------------------------------------------------
 -- DSL ab 0 Euro. -- statische IP -- UUCP -- Hosting -- Webshops --
---------------------------------------------------------------------

Re: cast not IMMUTABLE?

От
Alvaro Herrera
Дата:
On Thu, Mar 24, 2005 at 02:15:52PM +0100, Enrico Weigelt wrote:
> * Tom Lane <tgl@sss.pgh.pa.us> wrote:
> >
> > > why that cast is not considered IMMUTABLE ?
> >
> > Because it depends on your TimeZone setting.  Observe:
>
> BTW: whats really the difference between timezone and
> timezonetz ? I always used to use timestamp (w/o tz) and
> thought timestamptz was just an question of presentation.

The difference is that timestamptz converts the value from your local
timezone to UTC before storing; and at display time, it converts it back
to the local timezone.  So you can meaningfully compare data that was
inserted on different timezones.

Also, keep in mind that in past releases, "timestamp" was synonym for
"timestamp with time zone", while right now it is synonym for "timestamp
without time zone", and to get the former behavior you have to qualify
it with "with time zone" or use "timestamptz".  I think the switchover
was made in 7.3 but I don't remember exactly.

--
Alvaro Herrera (<alvherre[@]dcc.uchile.cl>)
"When the proper man does nothing (wu-wei),
his thought is felt ten thousand miles." (Lao Tse)