cast not IMMUTABLE?

Started by Gaetano Mendolaover 21 years ago7 messages
#1Gaetano Mendola
mendola@bigfoot.com

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

#2Sam Barnett-Cormack
s.barnett-cormack@lancaster.ac.uk
In reply to: Gaetano Mendola (#1)
Re: cast not IMMUTABLE?

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

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gaetano Mendola (#1)
Re: cast not IMMUTABLE?

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

#4Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Tom Lane (#3)
Re: [ADMIN] cast not IMMUTABLE?

(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?)

Seems reasonable...seems like the kind of thing that wouldn't have been
tested/considered...

Chris

#5Stephan Szabo
sszabo@megazone.bigpanda.com
In reply to: Gaetano Mendola (#1)
Re: cast not IMMUTABLE?

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.

#6Enrico Weigelt
weigelt@metux.de
In reply to: Tom Lane (#3)
Re: cast not IMMUTABLE?

* 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 --
---------------------------------------------------------------------

#7Alvaro Herrera
alvherre@dcc.uchile.cl
In reply to: Enrico Weigelt (#6)
Re: cast not IMMUTABLE?

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)