Обновление до PostgreSQL 11: функции, возвращающие множество, не разрешены в CASE - PullRequest
3 голосов
/ 13 июня 2019

Следующий запрос перестал работать при обновлении с PostgreSQL 9.6 до 11:

with doc as (select * from documents where name = doc_id)

select jsonb_array_elements_text(permissions)
from users
where users.name = user_name

union

select 
  case 
    when doc.reader = user_name then 'read'
    when doc.owner = user_name then unnest(array['read','write'])
    else unnest(array[]::text[])
    end 
from doc;

union как обычно объединяет два списка значений, оба списка могут иметь ноль,один или несколько элементов.

Первый select может возвращать ноль, один или несколько только потому, что это то, что находится в таблице users.

Второй select всегда сканирует одну строку из таблицы documents, но возвращает ноль, одну или несколько строк в зависимости от того, что решает case.

PostgreSQL 9.6 работал должным образом, PostgreSQL 11 говорит:

ERROR:  set-returning functions are not allowed in CASE
LINE 56:    else unnest(array[]::text[])
                 ^
HINT:  You might be able to move the set-returning function into a LATERAL FROM item.

Я ценю совет, но не могу понять, как использовать LATERAL FROM здесь.

1 Ответ

2 голосов
/ 13 июня 2019

Намек немного вводит в заблуждение здесь.Как говорится, добавление боковых объединений к функциям, возвращающим множество может помочь (в общем), но я не думаю, что в вашем случае это имеет смысл.

Вы можете легко работатьобойти это, изменив выражение CASE, чтобы оно возвращало массив, а затем аннулировать результат:

...
select 
  unnest(
    case 
      when doc.reader = user_name then array['read']
      when doc.owner = user_name then array['read','write']
      else array[]::text[]
    end
  )
from doc;
...