Параллельность в postgres в ctas с собственным агрегатом
Всем доброго
Поймал такое странное поведение Postgres:
- Создаём собственный агрегат
- Помечаем его как parallel = restricted
- Заставляем postgres выбрать параллельный план выполнения
- Пишем запрос со своим агрегатом, убеждаемся, что он работает
- Пишем выражение create table as select с нашим запросом
- Получаем ошибку
Для воспроизведения:
set max_parallel_workers_per_gather = 8;
set parallel_setup_cost = 0;
set parallel_tuple_cost = 0;
drop function if exists t_positive_sfunc cascade;
create function t_positive_sfunc (
i_balance numeric
, i_ccy_amt numeric
) returns numeric language sql parallel safe as $$
select greatest ( i_balance + coalesce ( i_ccy_amt, 0), 0);
$$;
drop aggregate if exists t_positive ( numeric);
create or replace aggregate t_positive ( numeric) (
sfunc = t_positive_sfunc
, stype = numeric
, initcond = 0
, parallel = restricted
);
drop table if exists test_data;
create table test_data as
select 1 as part_id, 1 as order_id, 1 as value union all
select 1 as part_id, 2 as order_id, 1 as value union all
select 2 as part_id, 1 as order_id, 1 as value union all
select 3 as part_id, 1 as order_id, 1 as value;
alter table test_data set ( parallel_workers = 8);
select t.part_id
, t.order_id
, t.value
, t_positive ( t.value)
over ( partition by t.part_id
order by t.order_id) as positive_value
from test_data t;
drop table if exists test_func;
create table test_func as
select t.part_id
, t.order_id
, t.value
, t_positive ( t.value)
over ( partition by t.part_id
order by t.order_id) as positive_value
from test_data t;
Получаемая ошибка:
[Code: 0, SQL State: XX000] ERROR: cannot start commands during a parallel operation
Где: SQL function "t_positive_sfunc"
Может кто сталкивался?
Версия postgresql - 16.8
Да, можно поставить parallel unsafe
Но хочется добиться параллельноло выполнения
Поэтому, собственно, и ctas, а не insert
Update - решил проблему, функцию t_positive_sfunc надо отметить как immutable и все работает
Не понятна механика, конечно
Почему тогда в целом параллельный запрос работает, и падает только в ctas
Источник: Stack Overflow на русском