Thread: expression index on date_trunc

expression index on date_trunc

From
a.redhead@openinternetsolutions.com
Date:
Hi,

is is possible to create an expression index based on the date_trunc function?

Working with PostgreSQL 8.2, I'm trying to create an index using:

  CREATE INDEX request_day_idx ON moksha_sm_request (date_trunc('day', request_received));

I get the error message:

  ERROR: functions in index expression must be marked IMMUTABLE
  SQL state: 42P17

I'd like to use the index to speed up a query that does a "group by" on the day part of a timestamp to lump all the
stuffthat happens in the same day together (I have a timestamp because the information in the table is coming from an
appserverlogfile and the date/time component of each line provides a full timestamptz (always the same tz!)). 

I'd be grateful if someone could point out what part of the statement is not IMMUTABLE or how I could mark my create
indexstatement as being immutable. 

Thanks,

Andy

Re: expression index on date_trunc

From
"Daniel Verite"
Date:
    A Redhead wrote:

>   CREATE INDEX request_day_idx ON moksha_sm_request
(date_trunc('day', request_received));
>
> I get the error message:
>
>   ERROR: functions in index expression must be marked IMMUTABLE
[...]
> I'd be grateful if someone could point out what part of the statement
is not IMMUTABLE
> or how I could mark my create index statement as being immutable.

The retrieved value of request_received depends on your current
timezone, and so does the result of date_trunc, that would be why it's
not immutable.
If you don't need that behavior, you can shift your timestamptz to a
fixed timezone, both in your index and in your queries, as in:

CREATE INDEX request_day_idx ON moksha_sm_request
  (date_trunc('day', request_received at time zone 'Europe/Paris'));

--
 Daniel
 PostgreSQL-powered mail user agent and storage:
http://www.manitou-mail.org

Re: expression index on date_trunc

From
Gregory Stark
Date:
<a.redhead@openinternetsolutions.com> writes:

>   CREATE INDEX request_day_idx ON moksha_sm_request (date_trunc('day', request_received));
...
> I'd be grateful if someone could point out what part of the statement is not
> IMMUTABLE or how I could mark my create index statement as being immutable.

date_trunc(timestamp with time zone) is not immutable because it depends what
your current time zone is. That is, if you change what time zone you're in a
timestamp with time zone could appear to change from one day to another.

However date_trunc(timestamp without time zone) is immutable. So I think what
you have to do is build your index on:

date_trunc('day', request_received AT TINE ZONE 'GMT')

or whatever time zone you're interested in. That will get you the day part of
that timestamp at that time zone (because it first casts it to a timestamp
without time zone for the time zone you specify).

--
  Gregory Stark
  EnterpriseDB          http://www.enterprisedb.com
  Get trained by Bruce Momjian - ask me about EnterpriseDB's PostgreSQL training!

Re: expression index on date_trunc

From
a.redhead@openinternetsolutions.com
Date:
><a.redhead@openinternetsolutions.com> writes:

>>   CREATE INDEX request_day_idx ON moksha_sm_request >(date_trunc('day',
>request_received));
>...
>> I'd be grateful if someone could point out what part of the statement >is not
>> IMMUTABLE or how I could mark my create index statement as being >immutable.

>date_trunc(timestamp with time zone) is not immutable because it >depends what
>your current time zone is. That is, if you change what time zone you're >in a
>timestamp with time zone could appear to change from one day to >another.

>However date_trunc(timestamp without time zone) is immutable. So I >think what
>you have to do is build your index on:

>date_trunc('day', request_received AT TINE ZONE 'GMT')

>or whatever time zone you're interested in. That will get you the day >part of
>that timestamp at that time zone (because it first casts it to a >timestamp
>without time zone for the time zone you specify).

That worked perfectly, many thanks.