Обсуждение: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

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

[GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
"Sven R. Kunze"
Дата:
Hello everybody,

I'd like to implement a btree date index from json input data.

>>># \d docs
                         Table "public.docs"
 Column |  Type   |                     Modifiers                    
--------+---------+---------------------------------------------------
 id     | integer | not null default nextval('docs_id_seq'::regclass)
 meta   | jsonb   |
Indexes:
    "docs_pkey" PRIMARY KEY, btree (id)

So, I did:

>>># create index docs_birth
date_idx ON docs using btree (((meta->>'birthdate')::date));
ERROR:  functions in index expression must be marked IMMUTABLE

Searching the Internet for a solution, I tried several variants of this:

>>># create index docs_birth
date_idx ON docs using btree ((to_timestamp(meta->>'birthdate', 'YYYY-MM-DD') at time zone 'UTC'));
ERROR:  functions in index expression must be marked IMMUTABLE

Years ago, I circumvented it by creating an immutable function. This, though, just hides the errors since I would use the mutable expression
anyway and mark it as immutable.


So, what is the problem here?


Regards,
Sven

Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
Geoff Winkless
Дата:
On 26 February 2017 at 10:09, Sven R. Kunze <srkunze@mail.de> wrote:
>>># create index docs_birthdate_idx ON docs using btree (((meta->>'birthdate')::date));
ERROR:  functions in index expression must be marked IMMUTABLE

So, what is the problem here?

​Date functions are inherently not immutable because of timezones. Your solution of using to_timestamp doesn't help because it automatically returns a value in WITH TIMESTAMP. Do you get anywhere by using "::timestamp without time zone" instead, as suggested here?


Geoff

Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
Adrian Klaver
Дата:
On 02/26/2017 07:56 AM, Geoff Winkless wrote:
> On 26 February 2017 at 10:09, Sven R. Kunze <srkunze@mail.de
> <mailto:srkunze@mail.de>>wrote:
>
>     >>># create index docs_birthdate_idx ON docs using btree
>     (((meta->>'birthdate')::date));
>     ERROR:  functions in index expression must be marked IMMUTABLE
>
>     So, what is the problem here?
>
>
> ​Date functions are inherently not immutable because of timezones. Your
> solution of using to_timestamp doesn't help because it automatically
> returns a value in WITH TIMESTAMP. Do you get anywhere by using
> "::timestamp without time zone" instead, as suggested here?

My attempts at working the OP's problem passed through that:

test=> create index docs_birthdate_idx ON docs using btree (((meta->>'birthdate')::timestamp));
ERROR:  functions in index expression must be marked IMMUTABLE

This works:

test=> create index docs_birthdate_idx ON docs using btree ((meta->>'birthdate'));
CREATE INDEX

It is the act of casting that fails. Other then the OP's own suggestion of creating
a function that wraps the operation and marks it immutable I don't have a solution at
this time.

>
> https://www.postgresql.org/message-id/4E039D16.20704%40pinpointresearch.com
>
> Geoff
>
> ​


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
Geoff Winkless
Дата:
On 26 February 2017 at 16:09, Adrian Klaver <adrian.klaver@aklaver.com> wrote:
On 02/26/2017 07:56 AM, Geoff Winkless wrote:
> On 26 February 2017 at 10:09, Sven R. Kunze <srkunze@mail.de
> <mailto:srkunze@mail.de>>wrote:
>
>     >>># create index docs_birthdate_idx ON docs using btree
>     (((meta->>'birthdate')::date));
>     ERROR:  functions in index expression must be marked IMMUTABLE
>
>     So, what is the problem here?
>
>
> ​Date functions are inherently not immutable because of timezones. Your
> solution of using to_timestamp doesn't help because it automatically
> returns a value in WITH TIMESTAMP. Do you get anywhere by using
> "::timestamp without time zone" instead, as suggested here?

​Of course I meant "WITH TIMEZONE" here, finger slippage.
My attempts at working the OP's problem passed through that:

​​Apologies, I don't have that reply in the thread in my mailbox.

test=> create index docs_birthdate_idx ON docs using btree (((meta->>'birthdate')::timestamp));
ERROR:  functions in index expression must be marked IMMUTABLE
 
​ Isn't the point that casting to ::timestamp will still keep the timezone?  Hence casting to "without timezone".

This works:

test=> create index docs_birthdate_idx ON docs using btree ((meta->>'birthdate'));
CREATE INDEX

It is the act of casting that fails. Other then the OP's own suggestion of creating
a function that wraps the operation and marks it immutable I don't have a solution at
this time

​I can imagine that without a cast, depending on the way birthdate is stored, it may behave differently to a cast index for ordering.

Geoff

Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
Tom Lane
Дата:
Geoff Winkless <pgsqladmin@geoff.dj> writes:
> On 26 February 2017 at 16:09, Adrian Klaver <adrian.klaver@aklaver.com>
> wrote:
>> On 02/26/2017 07:56 AM, Geoff Winkless wrote:
>>> On 26 February 2017 at 10:09, Sven R. Kunze <srkunze@mail.de
>>> <mailto:srkunze@mail.de>>wrote:
>>>> # create index docs_birthdate_idx ON docs using btree
>>>> (((meta->>'birthdate')::date));
>>>> ERROR:  functions in index expression must be marked IMMUTABLE

>>> ​Date functions are inherently not immutable because of timezones.

> ​ Isn't the point that casting to ::timestamp will still keep the
> timezone?  Hence casting to "without timezone".

There are multiple reasons why the text-to-datetime conversion functions
are not immutable:

* some of them depend on the current timezone (but I don't believe date_in
does);

* all of them depend on the current datestyle setting, eg to resolve
'02/03/2017';

* all of them accept strings with time-varying values, such as 'now'
or 'today'.

You could get around the second and third points with to_timestamp(),
but since the only variant of that is one that yields timestamptz and
hence is affected by the timezone setting, it's still not immutable.

I'm not entirely sure why the OP feels he needs an index on this
expression.  If he's willing to restrict the column to have the
exact format 'YYYY-MM-DD', then a regular textual index would sort
the same anyway.  Perhaps what's needed is just to add a CHECK
constraint verifying that the column has that format.

            regards, tom lane


Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
Adrian Klaver
Дата:
On 02/26/2017 08:15 AM, Geoff Winkless wrote:
> On 26 February 2017 at 16:09, Adrian Klaver <adrian.klaver@aklaver.com
> <mailto:adrian.klaver@aklaver.com>>wrote:
>
>     On 02/26/2017 07:56 AM, Geoff Winkless wrote:
>     > On 26 February 2017 at 10:09, Sven R. Kunze <srkunze@mail.de <mailto:srkunze@mail.de>
>     > <mailto:srkunze@mail.de <mailto:srkunze@mail.de>>>wrote:
>     >
>     >     >>># create index docs_birthdate_idx ON docs using btree
>     >     (((meta->>'birthdate')::date));
>     >     ERROR:  functions in index expression must be marked IMMUTABLE
>     >
>     >     So, what is the problem here?
>     >
>     >
>     > ​Date functions are inherently not immutable because of timezones. Your
>     > solution of using to_timestamp doesn't help because it automatically
>     > returns a value in WITH TIMESTAMP. Do you get anywhere by using
>     > "::timestamp without time zone" instead, as suggested here?
>
> ​Of course I meant "WITH TIMEZONE" here, finger slippage.

That does not work either:

test=> create index docs_birthdate_idx ON docs using btree
(((meta->>'birthdate')::timestamptz));
ERROR:  functions in index expression must be marked IMMUTABLE


> ​
>
>     My attempts at working the OP's problem passed through that:
>
> ​​Apologies, I don't have that reply in the thread in my mailbox.

No apologies needed I had not posted my attempts at that point. It was
more me thinking out loud.

> ​
>
>     test=> create index docs_birthdate_idx ON docs using btree
>     (((meta->>'birthdate')::timestamp));
>     ERROR:  functions in index expression must be marked IMMUTABLE
>
>
> ​ Isn't the point that casting to ::timestamp will still keep the
> timezone?  Hence casting to "without timezone".
>
>     This works:
>
>     test=> create index docs_birthdate_idx ON docs using btree
>     ((meta->>'birthdate'));
>     CREATE INDEX
>
>     It is the act of casting that fails. Other then the OP's own
>     suggestion of creating
>     a function that wraps the operation and marks it immutable I don't
>     have a solution at
>     this time
>
>
> ​I can imagine that without a cast, depending on the way birthdate is
> stored, it may behave differently to a cast index for ordering.
>
> Geoff


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
Adrian Klaver
Дата:
On 02/26/2017 08:50 AM, Tom Lane wrote:
> Geoff Winkless <pgsqladmin@geoff.dj> writes:
>> On 26 February 2017 at 16:09, Adrian Klaver <adrian.klaver@aklaver.com>
>> wrote:
>>> On 02/26/2017 07:56 AM, Geoff Winkless wrote:
>>>> On 26 February 2017 at 10:09, Sven R. Kunze <srkunze@mail.de
>>>> <mailto:srkunze@mail.de>>wrote:
>>>>> # create index docs_birthdate_idx ON docs using btree
>>>>> (((meta->>'birthdate')::date));
>>>>> ERROR:  functions in index expression must be marked IMMUTABLE
>
>>>> ​Date functions are inherently not immutable because of timezones.
>
>> ​ Isn't the point that casting to ::timestamp will still keep the
>> timezone?  Hence casting to "without timezone".
>
> There are multiple reasons why the text-to-datetime conversion functions
> are not immutable:
>
> * some of them depend on the current timezone (but I don't believe date_in
> does);
>
> * all of them depend on the current datestyle setting, eg to resolve
> '02/03/2017';
>
> * all of them accept strings with time-varying values, such as 'now'
> or 'today'.
>
> You could get around the second and third points with to_timestamp(),
> but since the only variant of that is one that yields timestamptz and
> hence is affected by the timezone setting, it's still not immutable.
>
> I'm not entirely sure why the OP feels he needs an index on this
> expression.  If he's willing to restrict the column to have the
> exact format 'YYYY-MM-DD', then a regular textual index would sort
> the same anyway.  Perhaps what's needed is just to add a CHECK
> constraint verifying that the column has that format.

The OP is trying to create an index on the value of a jsonb key. Would
the above still apply or am I misunderstanding the reference to column?

or

The below works:

test=> create index docs_birthdate_idx ON docs using btree
((meta->>'birthdate'));
CREATE INDEX

So if the text values of 'birthdate' are consistent the index would work
without the cast?

>
>             regards, tom lane
>


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
Tom Lane
Дата:
Adrian Klaver <adrian.klaver@aklaver.com> writes:
> On 02/26/2017 08:50 AM, Tom Lane wrote:
>> I'm not entirely sure why the OP feels he needs an index on this
>> expression.  If he's willing to restrict the column to have the
>> exact format 'YYYY-MM-DD', then a regular textual index would sort
>> the same anyway.  Perhaps what's needed is just to add a CHECK
>> constraint verifying that the column has that format.

> The OP is trying to create an index on the value of a jsonb key. Would
> the above still apply or am I misunderstanding the reference to column?

Sure, I was using "column" loosely to refer to the meta->>'birthdate'
expression.

> The below works:
> test=> create index docs_birthdate_idx ON docs using btree
> ((meta->>'birthdate'));
> CREATE INDEX
> So if the text values of 'birthdate' are consistent the index would work
> without the cast?

Yeah, seems to me you could do things like
    ... WHERE meta->>'birthdate' > '2017-02-26'
and it would Just Work, though I'd admit there's a deficiency of sanity
checking for the RHS constant in this example.

            regards, tom lane


Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
Adrian Klaver
Дата:
On 02/26/2017 09:42 AM, Tom Lane wrote:
> Adrian Klaver <adrian.klaver@aklaver.com> writes:
>> On 02/26/2017 08:50 AM, Tom Lane wrote:
>>> I'm not entirely sure why the OP feels he needs an index on this
>>> expression.  If he's willing to restrict the column to have the
>>> exact format 'YYYY-MM-DD', then a regular textual index would sort
>>> the same anyway.  Perhaps what's needed is just to add a CHECK
>>> constraint verifying that the column has that format.
>
>> The OP is trying to create an index on the value of a jsonb key. Would
>> the above still apply or am I misunderstanding the reference to column?
>
> Sure, I was using "column" loosely to refer to the meta->>'birthdate'
> expression.

Alright, thanks. It is just that with array/hstore/json(b) I see a table
in a column in a table and I need to be clear in my mind what is being
referred to.

>
>> The below works:
>> test=> create index docs_birthdate_idx ON docs using btree
>> ((meta->>'birthdate'));
>> CREATE INDEX
>> So if the text values of 'birthdate' are consistent the index would work
>> without the cast?
>
> Yeah, seems to me you could do things like
>     ... WHERE meta->>'birthdate' > '2017-02-26'
> and it would Just Work, though I'd admit there's a deficiency of sanity
> checking for the RHS constant in this example.
>
>             regards, tom lane
>


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
"Sven R. Kunze"
Дата:
Hi Geoff, Adrian and Tom,

thanks for your responses so far. Excuse my late response. I will respond to Tom's mail as it covers most points:

On 26.02.2017 17:50, Tom Lane wrote:
There are multiple reasons why the text-to-datetime conversion functions
are not immutable:

* some of them depend on the current timezone (but I don't believe date_in
does);

* all of them depend on the current datestyle setting, eg to resolve
'02/03/2017';

* all of them accept strings with time-varying values, such as 'now'
or 'today'.

You could get around the second and third points with to_timestamp(),
but since the only variant of that is one that yields timestamptz and
hence is affected by the timezone setting, it's still not immutable.

I understand that timezone settings can have serious consequences when parsing text to datetime.

My conceptual issue is that wrapping an "unsafe" operation up into a function and **marking** it as "safe" is not making things safer. Basically by-passing security guards.


So, what can I do to parse texts to date(times) in a safe manner?


I'd like to do it the right way. I can safely provide the timezone for those dates but it won't be in the jsonb data.

I'm not entirely sure why the OP feels he needs an index on this
expression.  If he's willing to restrict the column to have the
exact format 'YYYY-MM-DD', then a regular textual index would sort
the same anyway.  Perhaps what's needed is just to add a CHECK
constraint verifying that the column has that format.

These were my reasons:

1) sanity checks (already noted)
2) index date ranges (using gist)
3) maybe performance (comparing texts vs comparing dates) but I couldn't think of ways to test this



That's the current schema:
                         Table "public.docs"
 Column |  Type   |                     Modifiers                    
--------+---------+---------------------------------------------------
 id     | integer | not null default nextval('docs_id_seq'::regclass)
 meta   | jsonb   |
Indexes:
    "docs_pkey" PRIMARY KEY, btree (id)
    "docs_address_idx" gin (to_tsvector('english'::regconfig, meta ->> 'address'::text))
    "docs_address_trgm_idx" gin ((meta ->> 'address'::text) gin_trgm_ops)
    "docs_birthdate_idx" btree ((meta ->> 'birthdate'::text))
    "docs_meta_idx" gin (meta jsonb_path_ops)
    "docs_name_idx" gin (to_tsvector('english'::regconfig, meta ->> 'name'::text))


Thanks to the ISO date format, I got by with a btree index on birthdate as Tom suggested.


The index supports queries like the following (although 22secs still is not great on 10M rows)

explain analyze select meta->>'birthdate' from docs where meta->>'birthdate' > '2000-01-01' and meta->>'birthdate' < '2000-12-31' order by meta->>'birthdate';
                                                               QUERY PLAN                                                              
----------------------------------------------------------------------------------------------------------------------------------------
 Index Scan using docs_birthdate_idx on docs  (cost=0.43..46067.43 rows=50000 width=136) (actual time=2.118..22177.710 rows=209955 loops=1)
   Index Cond: (((meta ->> 'birthdate'::text) > '2000-01-01'::text) AND ((meta ->> 'birthdate'::text) < '2000-12-31'::text))
 Planning time: 0.205 ms
 Execution time: 22229.615 ms


Regard,
Sven

Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
Geoff Winkless
Дата:
On 27 February 2017 at 10:52, Sven R. Kunze <srkunze@mail.de> wrote:

So, what can I do to parse texts to date(times) in a safe manner?


You know best the format of your data; if you know that your date field is always in a particular style and timezone, you can write a function that can be considered safe to set IMMUTABLE, where a more generic​ system todate function cannot.

It might be sensible to call the function something that describes it exactly, rather than my_to_date you could call it utc_yyyymmdd_todate or something, just in case someone comes along later and sees an immutable todate function and thinks they can use it for something else.

Geoff

Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
"Sven R. Kunze"
Дата:
On 27.02.2017 12:10, Geoff Winkless wrote:
On 27 February 2017 at 10:52, Sven R. Kunze <srkunze@mail.de> wrote:

So, what can I do to parse texts to date(times) in a safe manner?


You know best the format of your data; if you know that your date field is always in a particular style and timezone, you can write a function that can be considered safe to set IMMUTABLE, where a more generic​ system todate function cannot.

It might be sensible to call the function something that describes it exactly, rather than my_to_date you could call it utc_yyyymmdd_todate or something, just in case someone comes along later and sees an immutable todate function and thinks they can use it for something else.

Geoff

Thanks, Geoff. It's not the most convenient way to define an index to define a function first and that all future queries need to use that very function in order to utilize the index. Though, it's the most safest and best documenting way.


So, I got two additional questions:

Why is this relevant for dates? I cannot see that dates are timezone-influenced.

I still feel that a function is overkill for a simple text to date conversion. Couldn't there be an IMMUTABLE modifier for an expression to mark it as immutable?


"SELECT '2007-02-02'::date;" just works. It would be great if one could define an index with the same ease. I already can see how our application developers need constant reminders that "in case of dates, use 'magic_function' first". If they don't, the application will suffer from bad performance.


Thanks in advance for your replies.

Regards,
Sven

Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
Adrian Klaver
Дата:
On 02/27/2017 07:03 AM, Sven R. Kunze wrote:
> On 27.02.2017 12:10, Geoff Winkless wrote:
>> On 27 February 2017 at 10:52, Sven R. Kunze <srkunze@mail.de
>> <mailto:srkunze@mail.de>>wrote:
>>
>>
>>     So, what can I do to parse texts to date(times) in a safe manner?
>>
>>
>> You know best the format of your data; if you know that your date
>> field is always in a particular style and timezone, you can write a
>> function that can be considered safe to set IMMUTABLE, where a more
>> generic​ system todate function cannot.
>>
>> It might be sensible to call the function something that describes it
>> exactly, rather than my_to_date you could call it utc_yyyymmdd_todate
>> or something, just in case someone comes along later and sees an
>> immutable todate function and thinks they can use it for something else.
>>
>> Geoff
>
> Thanks, Geoff. It's not the most convenient way to define an index to
> define a function first and that all future queries need to use that
> very function in order to utilize the index. Though, it's the most
> safest and best documenting way.
>
>
> So, I got two additional questions:
>
> Why is this relevant for dates? I cannot see that dates are
> timezone-influenced.

Per Tom's post, see points 2 & 3:

"* some of them depend on the current timezone (but I don't believe
date_in does);

* all of them depend on the current datestyle setting, eg to resolve
'02/03/2017';

* all of them accept strings with time-varying values, such as 'now'
or 'today'.

You could get around the second and third points with to_timestamp(),
but since the only variant of that is one that yields timestamptz and
hence is affected by the timezone setting, it's still not immutable.
"

>
> I still feel that a function is overkill for a simple text to date
> conversion. Couldn't there be an IMMUTABLE modifier for an expression to
> mark it as immutable?
>
>
> "SELECT '2007-02-02'::date;" just works. It would be great if one could
> define an index with the same ease. I already can see how our
> application developers need constant reminders that "in case of dates,
> use 'magic_function' first". If they don't, the application will suffer
> from bad performance.
>
>
> Thanks in advance for your replies.
>
> Regards,
> Sven


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
"Sven R. Kunze"
Дата:
On 27.02.2017 16:37, Adrian Klaver wrote:
> On 02/27/2017 07:03 AM, Sven R. Kunze wrote:
>> Why is this relevant for dates? I cannot see that dates are
>> timezone-influenced.
>
> Per Tom's post, see points 2 & 3:

Maybe, I am on a completely wrong track here, but to me dates still
don't look timezone dependent. They are just dates and not times, aren't
they?

> "* some of them depend on the current timezone (but I don't believe
> date_in does);
>
> * all of them depend on the current datestyle setting, eg to resolve
> '02/03/2017';
>
> * all of them accept strings with time-varying values, such as 'now'
> or 'today'.
>
> You could get around the second and third points with to_timestamp(),
> but since the only variant of that is one that yields timestamptz and
> hence is affected by the timezone setting, it's still not immutable.
> "

Reading this through again, I got an idea:

Wouldn't it be possible to provide an immutable variant of to_timestamp
and to_date with a third parameter to specify the otherwise
setting-dependent timezone?

>> I still feel that a function is overkill for a simple text to date
>> conversion. Couldn't there be an IMMUTABLE modifier for an expression to
>> mark it as immutable?

Any thoughts on this?


>> "SELECT '2007-02-02'::date;" just works. It would be great if one could
>> define an index with the same ease. I already can see how our
>> application developers need constant reminders that "in case of dates,
>> use 'magic_function' first". If they don't, the application will suffer
>> from bad performance.

Best regards,
Sven



Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
Adrian Klaver
Дата:
On 02/27/2017 09:08 AM, Sven R. Kunze wrote:
> On 27.02.2017 16:37, Adrian Klaver wrote:
>> On 02/27/2017 07:03 AM, Sven R. Kunze wrote:
>>> Why is this relevant for dates? I cannot see that dates are
>>> timezone-influenced.
>>
>> Per Tom's post, see points 2 & 3:
>
> Maybe, I am on a completely wrong track here, but to me dates still
> don't look timezone dependent. They are just dates and not times, aren't
> they?

Yes, but is not about timezone dependency, it is about the other
dependencies listed in the second and third points. Namely the datestyle
setting and magic strings e.g. 'now'

>
>> "* some of them depend on the current timezone (but I don't believe
>> date_in does);
>>
>> * all of them depend on the current datestyle setting, eg to resolve
>> '02/03/2017';
>>
>> * all of them accept strings with time-varying values, such as 'now'
>> or 'today'.
>>
>> You could get around the second and third points with to_timestamp(),
>> but since the only variant of that is one that yields timestamptz and
>> hence is affected by the timezone setting, it's still not immutable.
>> "
>
> Reading this through again, I got an idea:
>
> Wouldn't it be possible to provide an immutable variant of to_timestamp
> and to_date with a third parameter to specify the otherwise
> setting-dependent timezone?
>
>>> I still feel that a function is overkill for a simple text to date
>>> conversion. Couldn't there be an IMMUTABLE modifier for an expression to
>>> mark it as immutable?
>
> Any thoughts on this?
>
>
>>> "SELECT '2007-02-02'::date;" just works. It would be great if one could
>>> define an index with the same ease. I already can see how our
>>> application developers need constant reminders that "in case of dates,
>>> use 'magic_function' first". If they don't, the application will suffer
>>> from bad performance.
>
> Best regards,
> Sven
>
>
>


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
"Sven R. Kunze"
Дата:
On 27.02.2017 18:17, Adrian Klaver wrote:
Yes, but is not about timezone dependency, it is about the other dependencies listed in the second and third points. Namely the datestyle setting and magic strings e.g. 'now'

I am sorry, I still don't understand. to_date and to_timestamp require datestyle settings per se and magic strings don't work.


=# -- required datestyle
=# select to_date('2000-01-01');
ERROR:  function to_date(unknown) does not exist
LINE 1: select to_date('2000-01-01');
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.


=# -- magic strings don't work
=# select to_date('');

ERROR:  invalid value "epoc" for "YYYY"
DETAIL:  Value must be an integer.
=# select to_date('epoch', 'YYYY-MM-DD');
ERROR:  invalid value "epoc" for "YYYY"
DETAIL:  Value must be an integer.
=# select to_date('infinity', 'YYYY-MM-DD');

ERROR:  invalid value "infi" for "YYYY"
DETAIL:  Value must be an integer.
=# select to_date('-infinity', 'YYYY-MM-DD');
ERROR:  invalid value "-inf" for "YYYY"
DETAIL:  Value must be an integer.
=# select to_date('now', 'YYYY-MM-DD');
ERROR:  invalid value "now" for "YYYY"
DETAIL:  Value must be an integer.
=# select to_date('today', 'YYYY-MM-DD');
ERROR:  invalid value "toda" for "YYYY"
DETAIL:  Value must be an integer.
=# select to_date('tomorrow', 'YYYY-MM-DD');
ERROR:  invalid value "tomo" for "YYYY"
DETAIL:  Value must be an integer.
=# select to_date('yesterday', 'YYYY-MM-DD');
ERROR:  invalid value "yest" for "YYYY"
DETAIL:  Value must be an integer.
=# select to_date('allballs', 'YYYY-MM-DD');
ERROR:  invalid value "allb" for "YYYY"
DETAIL:  Value must be an integer.

Regards,
Sven

Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
Adrian Klaver
Дата:
On 02/28/2017 01:35 AM, Sven R. Kunze wrote:
> On 27.02.2017 18:17, Adrian Klaver wrote:
>> Yes, but is not about timezone dependency, it is about the other
>> dependencies listed in the second and third points. Namely the
>> datestyle setting and magic strings e.g. 'now'
>
> I am sorry, I still don't understand. to_date and to_timestamp require
> datestyle settings per se and magic strings don't work.

See here:

https://www.postgresql.org/message-id/11190.1488127834%40sss.pgh.pa.us

"There are multiple reasons why the text-to-datetime conversion
functions are not immutable"

Tom was referring to the text --> date cast you where attempting in your
original index definition:

create index docs_birthdate_idx ON docs using btree
(((meta->>'birthdate')::date));

So:

test=> select 'today'::date;
     date
------------
  2017-02-28
(1 row)

test=> select 'now'::date;
     date
------------
  2017-02-28
(1 row)

test=> set datestyle = 'SQL, DMY';
SET
test=> select 'today'::date;
     date
------------
  28/02/2017
(1 row)

test=> select 'now'::date;
     date
------------
  28/02/2017
(1 row)


Now you tried to work around the casting issue by using to_timestamp:

create index docs_birthdate_idx ON docs using btree
((to_timestamp(meta->>'birthdate', 'YYYY-MM-DD') at time zone 'UTC'));

but that introduced the issue that to_timestamp returns a timestamptz
and so you end up with a dependency on timezones.

>
>
> =# -- required datestyle
> =# select to_date('2000-01-01');
> ERROR:  function to_date(unknown) does not exist
> LINE 1: select to_date('2000-01-01');
>                ^
> HINT:  No function matches the given name and argument types. You might
> need to add explicit type casts.
>
>
> =# -- magic strings don't work
> =# select to_date('');
> ERROR:  invalid value "epoc" for "YYYY"
> DETAIL:  Value must be an integer.
> =# select to_date('epoch', 'YYYY-MM-DD');
> ERROR:  invalid value "epoc" for "YYYY"
> DETAIL:  Value must be an integer.
> =# select to_date('infinity', 'YYYY-MM-DD');
> ERROR:  invalid value "infi" for "YYYY"
> DETAIL:  Value must be an integer.
> =# select to_date('-infinity', 'YYYY-MM-DD');
> ERROR:  invalid value "-inf" for "YYYY"
> DETAIL:  Value must be an integer.
> =# select to_date('now', 'YYYY-MM-DD');
> ERROR:  invalid value "now" for "YYYY"
> DETAIL:  Value must be an integer.
> =# select to_date('today', 'YYYY-MM-DD');
> ERROR:  invalid value "toda" for "YYYY"
> DETAIL:  Value must be an integer.
> =# select to_date('tomorrow', 'YYYY-MM-DD');
> ERROR:  invalid value "tomo" for "YYYY"
> DETAIL:  Value must be an integer.
> =# select to_date('yesterday', 'YYYY-MM-DD');
> ERROR:  invalid value "yest" for "YYYY"
> DETAIL:  Value must be an integer.
> =# select to_date('allballs', 'YYYY-MM-DD');
> ERROR:  invalid value "allb" for "YYYY"
> DETAIL:  Value must be an integer.
>
> Regards,
> Sven


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
"Sven R. Kunze"
Дата:
On 28.02.2017 15:40, Adrian Klaver wrote:
> [explanation of why date casting and to_datetime don't work]

Why is to_date not immutable?

Regards,
Sven



Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
Adrian Klaver
Дата:
On 02/28/2017 07:30 AM, Sven R. Kunze wrote:
> On 28.02.2017 15:40, Adrian Klaver wrote:
>> [explanation of why date casting and to_datetime don't work]
>
> Why is to_date not immutable?

Not sure, but if I where to hazard a guess, from the source code in
formatting.c:


https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/adt/formatting.c;h=e552c8d20b61a082049068d2f8d776e35fef1179;hb=HEAD

to_date(PG_FUNCTION_ARGS)
{
         text       *date_txt = PG_GETARG_TEXT_P(0);
         text       *fmt = PG_GETARG_TEXT_P(1);
         DateADT         result;
         struct pg_tm tm;
         fsec_t          fsec;

         do_to_timestamp(date_txt, fmt, &tm, &fsec);
....

/*
  * do_to_timestamp: shared code for to_timestamp and to_date

The shared code makes it not immutable:


test=> select * from pg_proc where proname ilike 'to_date';
...

provolatile     | s

....


https://www.postgresql.org/docs/9.6/static/catalog-pg-proc.html

provolatile     char

provolatile tells whether the function's result depends only on its
input arguments, or is affected by outside factors. It is i for
"immutable" functions, which always deliver the same result for the same
inputs. It is s for "stable" functions, whose results (for fixed inputs)
do not change within a scan. It is v for "volatile" functions, whose
results might change at any time. (Use v also for functions with
side-effects, so that calls to them cannot get optimized away.)


>
> Regards,
> Sven
>
>
>


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
"David G. Johnston"
Дата:
On Tue, Feb 28, 2017 at 8:59 AM, Adrian Klaver <adrian.klaver@aklaver.com> wrote:
On 02/28/2017 07:30 AM, Sven R. Kunze wrote:
On 28.02.2017 15:40, Adrian Klaver wrote:
[explanation of why date casting and to_datetime don't work]

Why is to_date not immutable?

Not sure, but if I where to hazard a guess, from the source code in formatting.c:

https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/adt/formatting.c;h=e552c8d20b61a082049068d2f8d776e35fef1179;hb=HEAD

to_date(PG_FUNCTION_ARGS)
{
        text       *date_txt = PG_GETARG_TEXT_P(0);
        text       *fmt = PG_GETARG_TEXT_P(1);
        DateADT         result;
        struct pg_tm tm;
        fsec_t          fsec;

        do_to_timestamp(date_txt, fmt, &tm, &fsec);
....

/*
 * do_to_timestamp: shared code for to_timestamp and to_date

The shared code makes it not immutable:

​Further on that reads:

"​* Parse the 'date_txt' according to 'fmt', return results as a struct pg_tm
 * and fractional seconds."

Which makes it sound like a pure text parsing routine that applies minimal logic to the values that it is parsing.  In fact, its doesn't even accept a TZ/OF formatting codes that could be used to determine shift.  to_date is always to going to output a date value that reflects the literal input text with "positions" determined by the input format code.

Per Tom Lane [1] while the current implementation is in fact immutable at some point in the future we may wish to add additional environmental logic which will require that it be marked STABLE.


I would be considering a trigger that populates a date column and a normal index on said date column.

David J.


Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
Geoff Winkless
Дата:
On 28 February 2017 at 15:59, Adrian Klaver <adrian.klaver@aklaver.com> wrote:
On 02/28/2017 07:30 AM, Sven R. Kunze wrote:
On 28.02.2017 15:40, Adrian Klaver wrote:
[explanation of why date casting and to_datetime don't work]

Why is to_date not immutable?

Not sure, but if I where to hazard a guess, from the source code in formatting.c:

https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/adt/formatting.c;h=e552c8d20b61a082049068d2f8d776e35fef1179;hb=HEAD

​Would the fact that you can have month names in to_date strings make it dependent on current locale?

​Geoff

Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
"David G. Johnston"
Дата:
On Tue, Feb 28, 2017 at 9:35 AM, Geoff Winkless <pgsqladmin@geoff.dj> wrote:
On 28 February 2017 at 15:59, Adrian Klaver <adrian.klaver@aklaver.com> wrote:
On 02/28/2017 07:30 AM, Sven R. Kunze wrote:
On 28.02.2017 15:40, Adrian Klaver wrote:
[explanation of why date casting and to_datetime don't work]

Why is to_date not immutable?

Not sure, but if I where to hazard a guess, from the source code in formatting.c:

https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/adt/formatting.c;h=e552c8d20b61a082049068d2f8d776e35fef1179;hb=HEAD

​Would the fact that you can have month names in to_date strings make it dependent on current locale?


​That would seem to be it.

cache_locale_time() at the top of DCH_to_char which is in the call stack of the shared parsing code for both to_date and to_timestamp.


Supposedly one could provide a version of to_date that accepts a locale in which to interpret names in the input data - or extend the format string with some kind of "{locale=en_US}" syntax to avoid changing the function signature.

David J.

Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
"Sven R. Kunze"
Дата:
On 28.02.2017 17:50, David G. Johnston wrote:
​That would seem to be it.

cache_locale_time() at the top of DCH_to_char which is in the call stack of the shared parsing code for both to_date and to_timestamp.


Supposedly one could provide a version of to_date that accepts a locale in which to interpret names in the input data - or extend the format string with some kind of "{locale=en_US}" syntax to avoid changing the function signature.

David J.

I don't know if this is the right way and list to ask for this:

But if this is acceptable, I would be willing to contribute a patch to enable exactly this.


Regards,
Sven

Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
Geoff Winkless
Дата:
On 1 March 2017 at 13:36, Sven R. Kunze <srkunze@mail.de> wrote:
On 28.02.2017 17:50, David G. Johnston wrote:
Supposedly one could provide a version of to_date that accepts a locale in which to interpret names in the input data - or extend the format string with some kind of "{locale=en_US}" syntax to avoid changing the function signature.
if this is acceptable, I would be willing to contribute a patch to enable exactly this.

​I don't see how that would help. You can't set a function to be immutable for "some" inputs (ie where locale is specified in the format string).

The only way to do it would be to add to_date(string, string, string) where the third string specifies the locale, at which point I don't really see why you would gain anything over creating your own UDF.

Geoff​

Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
"Sven R. Kunze"
Дата:
On 01.03.2017 14:40, Geoff Winkless wrote:
On 1 March 2017 at 13:36, Sven R. Kunze <srkunze@mail.de> wrote:
On 28.02.2017 17:50, David G. Johnston wrote:
Supposedly one could provide a version of to_date that accepts a locale in which to interpret names in the input data - or extend the format string with some kind of "{locale=en_US}" syntax to avoid changing the function signature.
if this is acceptable, I would be willing to contribute a patch to enable exactly this.

​I don't see how that would help. You can't set a function to be immutable for "some" inputs (ie where locale is specified in the format string).

The only way to do it would be to add to_date(string, string, string) where the third string specifies the locale, at which point I don't really see why you would gain anything over creating your own UDF.

I don't consider rolling an UDF the best alternative especially after having looked through many solution proposals on the Web which just take an mutable expression and wrap them up in an immutable function.


An additional variant of to_date/to_timestamp would have the following advantages (point 2 is most important):

1) a single, recommended and easy way to parse date(times)
2) make people aware of the locale/timezone issue but give them a standard tool to solve it
3) make all those and related Google entries (https://www.google.de/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=postgresql+to_date+immutable&*) point to the same and safe solution eventually

Sven

Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
Geoff Winkless
Дата:
On 1 March 2017 at 14:23, Sven R. Kunze <srkunze@mail.de> wrote:
I don't consider rolling an UDF the best alternative especially after having looked through many solution proposals on the Web which just take an mutable expression and wrap them up in an immutable function.

​One alternative would be to make to_date accept all language variants of months simultaneously. A quick search of google suggests that there aren't any overlaps between languages (ie where one language uses "Foo" for March and another uses "Foo" for May), although you would have to​ do some more intense research to be sure. As far as I can see there's no other reason why to_date would need to be marked as stable/volatile, is there?

On the down side I imagine it would involve some potentially-prohibitively-large lookup tables; it would also end up with a technical incompatibility in that what ANSI SQL would reject as not-a-date might be parsed as a date. I'm not in a position to judge if either of those would be acceptable.

​Geoff​

Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
"Sven R. Kunze"
Дата:
On 03.03.2017 11:43, Geoff Winkless wrote:
One alternative would be to make to_date accept all language variants of months simultaneously. A quick search of google suggests that there aren't any overlaps between languages (ie where one language uses "Foo" for March and another uses "Foo" for May), although you would have to​ do some more intense research to be sure. As far as I can see there's no other reason why to_date would need to be marked as stable/volatile, is there?

I don't think so. It could be viable.

On the down side I imagine it would involve some potentially-prohibitively-large lookup tables; it would also end up with a technical incompatibility in that what ANSI SQL would reject as not-a-date might be parsed as a date.

There is another issue: languages change (admittedly very slowly) but I wouldn't want PostgreSQL to be incompatible with future generations.
Your performance argument weighs heavier, though.

I'm not in a position to judge if either of those would be acceptable.

Do you think I should post to pgsql-hackers?


Sven

Re: [GENERAL] ERROR: functions in index expression must be markedIMMUTABLE

От
"Sven R. Kunze"
Дата:
On 03.03.2017 11:43, Geoff Winkless wrote:
​One alternative would be to make to_date accept all language variants of months simultaneously. A quick search of google suggests that there aren't any overlaps between languages (ie where one language uses "Foo" for March and another uses "Foo" for May), although you would have to​ do some more intense research to be sure. As far as I can see there's no other reason why to_date would need to be marked as stable/volatile, is there?

As a side-note, it seems there are overlapping short months:


Using
this webpage http://web.library.yale.edu/cataloging/months.htm

this JS(Firefox) JSON.stringify([for (x of document.querySelectorAll('table.grid tr td')) x.textContent])
this Python

import pprint
from collections import defaultdict

def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]

a=<json output from Firefox>
a=list(chunks(a, 13))

dd=defaultdict(list)

for l in a:
     for i, m in enumerate(l):
         if i == 0:
             continue
         dd[m].append((i, l[0]))

pprint.pprint(dict(dd))
{'\nmart\n': [(3, 'Serbian')],
 'Ag.': [(8, 'Indonesian')],
 'Agustos': [(8, 'Turkish')],
 'Apr': [(4, 'Latin')],
 'Apr.': [(4, 'English'),
          (4, 'German'),
          (4, 'Greek, Modern'),
          (4, 'Indonesian'),
          (4, 'Malaysian'),
          (4, 'Romanian')],
 'Aralik': [(12, 'Turkish')],
 'Aug.': [(8, 'English'),
          (8, 'German'),
          (8, 'Greek, Modern'),
          (8, 'Latin'),
          (8, 'Romanian')],
 'Awst': [(8, 'Welsh')],
 'Chwef.': [(2, 'Welsh')],
 'Dec.': [(12, 'English'), (12, 'Latin'), (12, 'Romanian')],
 'Dek.': [(12, 'Greek, Modern')],
 'Des.': [(12, 'Indonesian')],
 'Dez.': [(12, 'German')],
 'Dis.': [(12, 'Malaysian')],
 'Ebr.': [(4, 'Welsh')],
 'Ekim': [(10, 'Turkish')],
 'Eylul': [(9, 'Turkish')],
 'Feb.': [(2, 'English'), (2, 'German'), (2, 'Malaysian'), (2, 'Romanian')],
 'Febr.': [(2, 'Latin')],
 'Gorff.': [(7, 'Welsh')],
 'Haziran': [(6, 'Turkish')],
 'Hyd.': [(10, 'Welsh')],
 'Ian.': [(1, 'Greek, Modern'), (1, 'Latin'), (1, 'Romanian')],
 'Ion.': [(1, 'Welsh')],
 'Ioul.': [(7, 'Greek, Modern')],
 'Ioun.': [(6, 'Greek, Modern')],
 'Iul.': [(7, 'Latin')],
 'Iulie': [(7, 'Romanian')],
 'Iun.': [(6, 'Latin')],
 'Iunie': [(6, 'Romanian')],
 'Jan.': [(1, 'English'), (1, 'Malaysian')],
 'Jan./Djan.\xc2\xa0': [(1, 'Indonesian')],
 'Jan./J\xc3\xa4n.': [(1, 'German')],
 'Julai': [(7, 'Malaysian')],
 'Juli': [(7, 'German')],
 'Juli/Djuli': [(7, 'Indonesian')],
 'July': [(7, 'English')],
 'Jun': [(6, 'Malaysian')],
 'June': [(6, 'English')],
 'Juni': [(6, 'German')],
 'Juni/Djuni': [(6, 'Indonesian')],
 'Kasim': [(11, 'Turkish')],
 'Mac': [(3, 'Malaysian')],
 'Mai': [(5, 'German'), (5, 'Romanian'), (5, 'Welsh')],
 'Mai.': [(5, 'Latin')],
 'Maios': [(5, 'Greek, Modern')],
 'Mar.': [(3, 'English'), (3, 'Romanian')],
 'Mart.': [(3, 'Greek, Modern'), (3, 'Latin')],
 'Maw.': [(3, 'Welsh')],
 'May': [(5, 'English')],
 'Mayis': [(5, 'Turkish')],
 'Medi': [(9, 'Welsh')],
 'Meh.': [(6, 'Welsh')],
 'Mei': [(5, 'Malaysian')],
 'Mei/Mai': [(5, 'Indonesian')],
 'Mrt.': [(3, 'Indonesian')],
 'M\xc3\xa4rz': [(3, 'German')],
 'Nisan': [(4, 'Turkish')],
 'Noem.': [(11, 'Greek, Modern')],
 'Noiem.': [(11, 'Romanian')],
 'Nop.': [(11, 'Indonesian')],
 'Nov.': [(11, 'English'), (11, 'German'), (11, 'Latin'), (11, 'Malaysian')],
 'Ocak': [(1, 'Turkish')],
 'Oct.': [(10, 'English'), (10, 'Latin'), (10, 'Romanian')],
 'Og': [(8, 'Malaysian')],
 'Okt.': [(10, 'German'),
          (10, 'Greek, Modern'),
          (10, 'Indonesian'),
          (10, 'Malaysian')],
 'Peb.': [(2, 'Indonesian')],
 'Phevr.': [(2, 'Greek, Modern')],
 'Rhag.': [(12, 'Welsh')],
 'Saus.': [(1, 'Lithuanian')],
 'Sept.': [(9, 'English'),
           (9, 'German'),
           (9, 'Greek, Modern'),
           (9, 'Indonesian'),
           (9, 'Latin'),
           (9, 'Malaysian'),
           (9, 'Romanian')],
 'Subat': [(2, 'Turkish')],
 'Tach.': [(11, 'Welsh')],
 'Temmuz': [(7, 'Turkish')],
 'abr.': [(4, 'Spanish')],
 'abril': [(4, 'Portuguese')],
 'ag.': [(8, 'Italian')],
 'agosto': [(8, 'Portuguese'), (8, 'Spanish')],
 'ao\xc3\xbbt': [(8, 'French')],
 'apr.': [(4, 'Dutch'),
          (4, 'Estonian'),
          (4, 'Italian'),
          (4, 'Latvian'),
          (4, 'Russian')],
 'apr./mali traven': [(4, 'Slovenian')],
 'april': [(4, 'Bosnian'),
           (4, 'Bulgarian'),
           (4, 'Danish'),
           (4, 'Norwegian'),
           (4, 'Serbian'),
           (4, 'Swedish')],
 'aug.': [(8, 'Bosnian'),
          (8, 'Danish'),
          (8, 'Dutch'),
          (8, 'Estonian'),
          (8, 'Hungarian'),
          (8, 'Latvian'),
          (8, 'Norwegian'),
          (8, 'Swedish')],
 'avg.': [(8, 'Bulgarian'), (8, 'Russian'), (8, 'Serbian')],
 'avg./veliki\xc2\xa0srpan': [(8, 'Slovenian')],
 'avril': [(4, 'French')],
 'bal.': [(4, 'Lithuanian')],
 'ber.': [(3, 'Ukranian')],
 'birz': [(6, 'Lithuanian')],
 'brez.': [(3, 'Czech')],
 'brez./mar.': [(3, 'Slovak')],
 'cerv.': [(6, 'Czech')],
 'cerv./j\xc3\xban': [(6, 'Slovak')],
 'cerven.': [(7, 'Czech')],
 'cerven./j\xc3\xbal': [(7, 'Slovak')],
 'cher.': [(6, 'Ukranian')],
 'cherv.': [(6, 'Belorusian')],
 'czerw.': [(6, 'Polish')],
 'dec.': [(12, 'Danish'),
          (12, 'Dutch'),
          (12, 'Hungarian'),
          (12, 'Latvian'),
          (12, 'Serbian'),
          (12, 'Swedish')],
 'dec./gr.': [(12, 'Slovenian')],
 'dec.\xc2\xa0': [(12, 'Bosnian')],
 'dek.': [(12, 'Bulgarian'), (12, 'Russian')],
 'des.': [(12, 'Norwegian')],
 'dets.': [(12, 'Estonian')],
 'dez.': [(12, 'Portuguese')],
 'dic.': [(12, 'Italian'), (12, 'Spanish')],
 'dub.': [(4, 'Czech')],
 'dub./apr.': [(4, 'Slovak')],
 'd\xc3\xa9c.': [(12, 'French')],
 'enero': [(1, 'Spanish')],
 'feb.': [(2, 'Bosnian'),
          (2, 'Dutch'),
          (2, 'Hungarian'),
          (2, 'Latvian'),
          (2, 'Spanish')],
 'feb./svec.': [(2, 'Slovenian')],
 'febbr.': [(2, 'Italian')],
 'febr.': [(2, 'Danish'), (2, 'Norwegian'), (2, 'Serbian'), (2, 'Swedish')],
 'fev.': [(2, 'Portuguese')],
 'fevr.': [(2, 'Bulgarian'), (2, 'Russian')],
 'f\xc3\xa9vr.': [(2, 'French')],
 'geg.': [(5, 'Lithuanian')],
 'genn.': [(1, 'Italian')],
 'giugno': [(6, 'Italian')],
 'gr.': [(12, 'Lithuanian')],
 'grudz.': [(12, 'Polish')],
 'hrud.': [(12, 'Ukranian')],
 'ian.': [(1, 'Bulgarian')],
 'ianv.': [(1, 'Russian')],
 "iiul'": [(7, 'Russian')],
 "iiun'": [(6, 'Russian')],
 'iuli': [(7, 'Bulgarian')],
 'iuni': [(6, 'Bulgarian')],
 'jaan.': [(1, 'Estonian')],
 'jan.': [(1, 'Bosnian'),
          (1, 'Danish'),
          (1, 'Dutch'),
          (1, 'Hungarian'),
          (1, 'Latvian'),
          (1, 'Norwegian'),
          (1, 'Portuguese'),
          (1, 'Serbian'),
          (1, 'Swedish')],
 'jan./pros.': [(1, 'Slovenian')],
 'janv.': [(1, 'French')],
 'juil.': [(7, 'French')],
 'juin': [(6, 'French')],
 'jul.': [(7, 'Hungarian'), (7, 'Spanish')],
 'jul./mali srpan': [(7, 'Slovenian')],
 'julho': [(7, 'Portuguese')],
 'juli': [(7, 'Bosnian'),
          (7, 'Danish'),
          (7, 'Dutch'),
          (7, 'Norwegian'),
          (7, 'Serbian'),
          (7, 'Swedish')],
 'julijs': [(7, 'Latvian')],
 'jun.': [(6, 'Hungarian'), (6, 'Spanish')],
 'jun./roz.': [(6, 'Slovenian')],
 'junho': [(6, 'Portuguese')],
 'juni': [(6, 'Bosnian'),
          (6, 'Danish'),
          (6, 'Dutch'),
          (6, 'Norwegian'),
          (6, 'Serbian'),
          (6, 'Swedish')],
 'junijs': [(6, 'Latvian')],
 'juuli': [(7, 'Estonian')],
 'juuni': [(6, 'Estonian')],
 'kastr.': [(10, 'Belorusian')],
 'kol.': [(8, 'Croatian')],
 'kovas': [(3, 'Lithuanian')],
 'kras.': [(4, 'Belorusian')],
 'kvet.': [(5, 'Czech')],
 'kvet/m\xc3\xa1j': [(5, 'Slovak')],
 'kvit.': [(4, 'Ukranian')],
 'kwiec.': [(4, 'Polish')],
 "l'ad./jan.": [(1, 'Slovak')],
 'lapkr.': [(11, 'Lithuanian')],
 'led.': [(1, 'Czech')],
 'liepa': [(7, 'Lithuanian')],
 'lip.': [(7, 'Belorusian'), (6, 'Croatian'), (7, 'Polish')],
 'list.': [(11, 'Belorusian'), (10, 'Croatian'), (11, 'Czech')],
 'list./nov.': [(11, 'Slovak')],
 'listop.': [(11, 'Polish')],
 'liut.': [(2, 'Belorusian'), (2, 'Ukranian')],
 'luglio': [(7, 'Italian')],
 'luty': [(2, 'Polish')],
 'lyp.': [(7, 'Ukranian')],
 'lyst.': [(11, 'Ukranian')],
 'maart': [(3, 'Dutch')],
 'magg.': [(5, 'Italian')],
 'mai': [(5, 'Bulgarian'),
         (5, 'Estonian'),
         (5, 'French'),
         (5, 'Norwegian'),
         (5, 'Russian')],
 'maijs': [(5, 'Latvian')],
 'maio': [(5, 'Portuguese')],
 'maj': [(5, 'Bosnian'),
         (5, 'Danish'),
         (5, 'Polish'),
         (5, 'Serbian'),
         (5, 'Swedish')],
 'maj./veliki traven': [(5, 'Slovenian')],
 'mar.': [(3, 'Italian'), (3, 'Polish')],
 'mar./sus.': [(3, 'Slovenian')],
 'mars': [(3, 'French'), (3, 'Norwegian'), (3, 'Swedish')],
 'mart': [(3, 'Bosnian'), (3, 'Bulgarian'), (3, 'Russian'), (3, 'Turkish')],
 'marts': [(3, 'Danish'), (3, 'Latvian')],
 'marzo': [(3, 'Spanish')],
 'mar\xc3\xa7o': [(3, 'Portuguese')],
 'mayo': [(5, 'Spanish')],
 'mei': [(5, 'Dutch')],
 'm\xc3\xa1j.': [(5, 'Hungarian')],
 'm\xc3\xa1rc.': [(3, 'Hungarian')],
 'm\xc3\xa4rts': [(3, 'Estonian')],
 'noem.': [(11, 'Bulgarian')],
 "noiabr'": [(11, 'Russian')],
 'nov.': [(11, 'Bosnian'),
          (11, 'Danish'),
          (11, 'Dutch'),
          (11, 'Estonian'),
          (11, 'French'),
          (11, 'Hungarian'),
          (11, 'Italian'),
          (11, 'Latvian'),
          (11, 'Norwegian'),
          (11, 'Portuguese'),
          (11, 'Serbian'),
          (11, 'Spanish'),
          (11, 'Swedish')],
 'nov./list.': [(11, 'Slovenian')],
 'oct.': [(10, 'French'), (10, 'Spanish')],
 'oct./okt.': [(10, 'Dutch')],
 'okt.': [(10, 'Bosnian'),
          (10, 'Bulgarian'),
          (10, 'Danish'),
          (10, 'Estonian'),
          (10, 'Hungarian'),
          (10, 'Latvian'),
          (10, 'Norwegian'),
          (10, 'Russian'),
          (10, 'Serbian'),
          (10, 'Swedish')],
 'okt./vino.': [(10, 'Slovenian')],
 'ott.': [(10, 'Italian')],
 'out.': [(10, 'Portuguese')],
 'ozuj.': [(3, 'Croatian')],
 'pazdz.': [(10, 'Polish')],
 'pros.': [(12, 'Croatian'), (12, 'Czech')],
 'pros./dec.': [(12, 'Slovak')],
 'rugp.': [(8, 'Lithuanian')],
 'rugs.': [(9, 'Lithuanian')],
 'ruj.': [(9, 'Croatian')],
 'ruj./okt.': [(10, 'Slovak')],
 'r\xc3\xadj.': [(10, 'Czech')],
 'sak./mar.': [(3, 'Belorusian')],
 'sent.': [(9, 'Russian')],
 'sept.': [(9, 'Bosnian'),
           (9, 'Bulgarian'),
           (9, 'Danish'),
           (9, 'Dutch'),
           (9, 'Estonian'),
           (9, 'French'),
           (9, 'Latvian'),
           (9, 'Norwegian'),
           (9, 'Serbian'),
           (9, 'Swedish')],
 'sept./kim.': [(9, 'Slovenian')],
 'sept./set.': [(9, 'Spanish')],
 'serp.': [(8, 'Ukranian')],
 'set.': [(9, 'Portuguese')],
 'sett.': [(9, 'Italian')],
 'sich.': [(1, 'Ukranian')],
 'sierp.': [(8, 'Polish')],
 'sijec.': [(1, 'Croatian')],
 'snezh.': [(12, 'Belorusian')],
 'spalis': [(10, 'Lithuanian')],
 'srp.': [(7, 'Croatian'), (8, 'Czech')],
 'srp./aug.': [(8, 'Slovak')],
 'stud.': [(11, 'Croatian')],
 'studz.': [(1, 'Belorusian')],
 'stycz.': [(1, 'Polish')],
 'svib.': [(5, 'Croatian')],
 'szept.': [(9, 'Hungarian')],
 'trav.': [(5, 'Belorusian'), (4, 'Croatian'), (5, 'Ukranian')],
 'vas.': [(2, 'Lithuanian')],
 'veebr.': [(2, 'Estonian')],
 'velj.': [(2, 'Croatian')],
 'ver.': [(9, 'Ukranian')],
 'veras.': [(9, 'Belorusian')],
 'wrzes.': [(9, 'Polish')],
 "zhniven'": [(8, 'Belorusian')],
 'zhovt.': [(10, 'Ukranian')],
 'z\xc3\xa1r.': [(9, 'Czech')],
 'z\xc3\xa1ri./sept.': [(9, 'Slovak')],
 '\xc3\xa1pr.': [(4, 'Hungarian')],
 '\xc3\xban.': [(2, 'Czech')],
 '\xc3\xban./feb.': [(2, 'Slovak')]}


Sven

Re: [GENERAL] ERROR: functions in index expression must be marked IMMUTABLE

От
Geoff Winkless
Дата:
On 3 March 2017 at 12:17, Sven R. Kunze <srkunze@mail.de> wrote:
On 03.03.2017 11:43, Geoff Winkless wrote:
​One alternative would be to make to_date accept all language variants of months simultaneously. A quick search of google suggests that there aren't any overlaps between languages (ie where one language uses "Foo" for March and another uses "Foo" for May), although you would have to​ do some more intense research to be sure. As far as I can see there's no other reason why to_date would need to be marked as stable/volatile, is there?

it seems there are overlapping short months:
 
Trust the Balkan states to find something to disagree over :)

Oh well, that scrubs that idea then.

Geoff