Материализованное представление Postgres скрывает некоторые данные

Прежде всего, я не могу воссоздать этот пример в скрипте SQL, я получил некоторую ошибку при попытке выбрать из представления.

Проблема:

У меня есть материализованное представление, которое извлекает параметры функции из моей схемы на основе information_schema. Когда я его создаю, он отлично работает. Когда я обновляю его, он работает нормально. Когда я назначаю ему какую-то роль, а затем обновляю - он теряет около 75% своего содержимого, и обновление не работает. Единственное, что работает, - это отбрасывание и воссоздание всего представления.

Примеры:

Все примеры были выполнены как суперпользователь. Допустим, у меня есть роль:

 CREATE ROLE table_owner NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;

И я материализовал такое представление:

CREATE MATERIALIZED VIEW function_def AS 
    SELECT 
        regexp_replace(r.specific_name::text, '^(.*)_[0-9]+$'::text, '\1'::text) AS function_name,
        r.data_type AS output_type,
        r.type_udt_name AS output_udt_name,
        p.ordinal_position,
        p.parameter_name,
        p.data_type,
        p.udt_schema,
        regexp_replace(p.udt_name::text, '^_'::text, ''::text) AS udt_name
    FROM information_schema.routines r
    LEFT JOIN information_schema.parameters p ON p.specific_name::text = r.specific_name::text
    WHERE 1 = 1 AND p.specific_schema::text = 'mySchema'::text
    ORDER BY regexp_replace(r.specific_name::text, '^(.*)_[0-9]+$'::text, '\1'::text), p.ordinal_position
WITH DATA;
CREATE INDEX i_function_def_function_name ON function_def(function_name);

И скажем, что в этом заявлении точки:

SElECT count(*) FROM function_def

возвращает 231 строку, что является правильным числом. Затем я назначаю владение представлением некоторой роли:

ALTER TABLE function_def OWNER TO table_owner;

и select по-прежнему возвращает 231 строку, что является правильным числом.

SElECT count(*) FROM function_def;

но когда я обновляю вид вот так:

REFRESH MATERIALIZED VIEW function_def WITH DATA;

а потом:

SElECT count(*) FROM function_def;

возвращаемое количество строк равно 54, что неверно.

Я здесь весьма озадачен и был бы признателен за помощь или подсказку. Это ошибка postgres или я что-то не так делаю?

РЕДАКТИРОВАТЬ - решение:

Как заявил Клин, это на самом деле вопрос привилегий! Поскольку все мои функции принадлежат function_owner, этот код сработал, и теперь все в порядке:

ALTER TABLE function_def OWNER TO function_owner;
GRANT SELECT ON TABLE function_def TO GROUP table_owner;

person T.Z.    schedule 20.08.2015    source источник
comment
Возможно ли, что у вас нет прав на доступ к information_schema.routines, но вы видите проблему только тогда, когда обновляете ее.   -  person Edmon    schedule 20.08.2015
comment
@Edmon Нет, потому что представления действуют с привилегиями владельца представления   -  person Craig Ringer    schedule 21.08.2015
comment
@Edmon, все операторы выполнялись от имени суперпользователя, у которого также есть роль table_owner. Так что привилегии здесь не должны быть проблемой ...   -  person T.Z.    schedule 21.08.2015


Ответы (1)


REFRESH MATERIALIZED VIEW выполняется с привилегиями владельца представления, то есть в данном случае table_owner. У пользователя нет доступа к некоторым функциям, и поэтому он не видит некоторые записи в information_schema.routines.

Вы можете проверить, какие функции недоступны table_owner, выполнив этот запрос от имени суперпользователя:

SELECT 
    regexp_replace(r.specific_name::text, '^(.*)_[0-9]+$'::text, '\1'::text) AS function_name,
    r.data_type AS output_type,
    r.type_udt_name AS output_udt_name,
    p.ordinal_position,
    p.parameter_name,
    p.data_type,
    p.udt_schema,
    regexp_replace(p.udt_name::text, '^_'::text, ''::text) AS udt_name
FROM information_schema.routines r
LEFT JOIN information_schema.parameters p ON p.specific_name::text = r.specific_name::text
WHERE 1 = 1 AND p.specific_schema::text = 'mySchema'::text

EXCEPT

SELECT * FROM function_def;
person klin    schedule 24.08.2015