Bug / Unintentional Feature: non-immutable functions can be used for generated columns.

Поиск
Список
Период
Сортировка
Искать
От
Shane Plesner
Тема
Bug / Unintentional Feature: non-immutable functions can be used for generated columns.
Дата
Msg-id
CAFBci=qAOea1SCwkJgLdR6OwLOBVTuHqmqDGz8jKMFUzZd1b5g@mail.gmail.com
Список
Дерево обсуждения
Bug / Unintentional Feature: non-immutable functions can be used for generated columns. Shane Plesner <gebnar@gmail.com>
Re: Bug / Unintentional Feature: non-immutable functions can be used for generated columns. "David G. Johnston" <david.g.johnston@gmail.com>
Re: Bug / Unintentional Feature: non-immutable functions can be used for generated columns. Shane Plesner <gebnar@gmail.com>
Re: Bug / Unintentional Feature: non-immutable functions can be used for generated columns. Tom Lane <tgl@sss.pgh.pa.us>
Important preface: This "bug" turns out to enable functionality that is extremely useful. Please carefully consider how the usefulness of this can be retained when "fixing" the bug.

No error or warning or behavioral problems occur if the function used to fill a generated column is replaced with a non-immutable version after it is assigned as the column generator.

SQL which reproduces this issue, as well as showing one valid (useful) use-case for why this isn't a bad thing in itself:

create function gen_tmp() returns text
language plpgsql
immutable
as $$
declare
_tmp text;
begin
loop
select 'C-'||array_to_string(array(select substr('ABCDEFGHJKLMNPQRSTUVWXYZ0123456789',((random()*(33)+1)::integer),1) from generate_series(1,8)),'') into _tmp;
exit when not exists(select 1 from tmp where k = _tmp);
end loop;
return _tmp;
end
$$;


create table tmp(
k text unique primary key generated always as (gen_tmp()) stored,
v text
);

create or replace function gen_tmp() returns text
language plpgsql
as $$
declare
_tmp text;
begin
loop
select 'C-'||array_to_string(array(select substr('ABCDEFGHJKLMNPQRSTUVWXYZ0123456789',((random()*(33)+1)::integer),1) from generate_series(1,8)),'') into _tmp;
exit when not exists(select 1 from tmp where k = _tmp);
end loop;
return _tmp;
end
$$;

insert into tmp (v) select 'test' from generate_series(1,10);

select * from tmp;


Discovered by Shane Plesner, by accident, about 10 minutes ago...
В списке pgsql-bugs по дате отправления
От: David G. Johnston
Дата:
FAQ