Thread: cast not IMMUTABLE?
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
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
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
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.
* 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 -- ---------------------------------------------------------------------
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)