Postgres物化视图隐藏了一些数据
Postgres materialized view hides some data
首先,我无法在 SQL fiddle 中重新创建此示例,当我从视图中尝试 select 时遇到了一些错误。
问题:
我有一个物化视图,它基于 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, ''::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, ''::text), p.ordinal_position
WITH DATA;
CREATE INDEX i_function_def_function_name ON function_def(function_name);
让我们在这一点陈述中说:
SElECT count(*) FROM function_def
returns 231 行,这是正确的数字。然后我将视图的所有权分配给某个角色:
ALTER TABLE function_def OWNER TO table_owner;
和select仍然是returns 231行,这是正确的数字。
SElECT count(*) FROM function_def;
但是当我像这样刷新视图时:
REFRESH MATERIALIZED VIEW function_def WITH DATA;
然后:
SElECT count(*) FROM function_def;
返回的行数是常数54,这是不正确的。
我在这里很困惑,希望得到一些帮助或提示。这是一个 postgres 错误,还是我做错了什么?
编辑 - 解决方案:
正如Klin所说,其实是权限问题!因为我所有的函数都属于function_owner,这段代码已经成功了,现在一切正常:
ALTER TABLE function_def OWNER TO function_owner;
GRANT SELECT ON TABLE function_def TO GROUP table_owner;
REFRESH MATERIALIZED VIEW
以视图所有者的权限执行,即在本例中为 table_owner
。
用户无法访问某些功能,因此他在 information_schema.routines
.
中看不到某些记录
您可以通过以超级用户身份执行此查询来检查 table_owner
无法访问哪些功能:
SELECT
regexp_replace(r.specific_name::text, '^(.*)_[0-9]+$'::text, ''::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;
首先,我无法在 SQL fiddle 中重新创建此示例,当我从视图中尝试 select 时遇到了一些错误。
问题:
我有一个物化视图,它基于 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, ''::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, ''::text), p.ordinal_position
WITH DATA;
CREATE INDEX i_function_def_function_name ON function_def(function_name);
让我们在这一点陈述中说:
SElECT count(*) FROM function_def
returns 231 行,这是正确的数字。然后我将视图的所有权分配给某个角色:
ALTER TABLE function_def OWNER TO table_owner;
和select仍然是returns 231行,这是正确的数字。
SElECT count(*) FROM function_def;
但是当我像这样刷新视图时:
REFRESH MATERIALIZED VIEW function_def WITH DATA;
然后:
SElECT count(*) FROM function_def;
返回的行数是常数54,这是不正确的。
我在这里很困惑,希望得到一些帮助或提示。这是一个 postgres 错误,还是我做错了什么?
编辑 - 解决方案:
正如Klin所说,其实是权限问题!因为我所有的函数都属于function_owner,这段代码已经成功了,现在一切正常:
ALTER TABLE function_def OWNER TO function_owner;
GRANT SELECT ON TABLE function_def TO GROUP table_owner;
REFRESH MATERIALIZED VIEW
以视图所有者的权限执行,即在本例中为 table_owner
。
用户无法访问某些功能,因此他在 information_schema.routines
.
您可以通过以超级用户身份执行此查询来检查 table_owner
无法访问哪些功能:
SELECT
regexp_replace(r.specific_name::text, '^(.*)_[0-9]+$'::text, ''::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;