【问题标题】:Postgres materialized view hides some dataPostgres物化视图隐藏了一些数据
【发布时间】:2015-11-14 07:35:01
【问题描述】:

首先,我无法在 SQL fiddle 中重新创建此示例,当我尝试从视图中选择时遇到了一些错误。

问题:

我有一个物化视图,它根据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;

并且选择仍然返回 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;

【问题讨论】:

  • 有没有可能是你没有访问information_schema.routines的权限,但是刷新才看到问题。
  • @Edmon 不,因为视图具有视图所有者的权限
  • @Edmon,所有语句都以超级用户身份执行,该用户也具有 table_owner 角色。所以这里的特权应该不是问题......

标签: postgresql materialized-views information-schema postgresql-9.4


【解决方案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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    相关资源
    最近更新 更多