创建一个物化视图,它继承进行视图调用的用户的权限

Creating a materialized view which inherits the permissions of the user making the view call

我正在尝试在函数中创建实体化视图,该视图需要获得用户从我的应用程序中进行视图调用的权限。我知道这可以在函数中完成,但是在我的函数中创建视图时,有没有办法在视图上执行此操作?

简而言之 — 我在函数中创建视图;有没有办法在函数内授予对视图的权限?

CREATE OR REPLACE FUNCTION schema.my_function()
     RETURNS void AS $body$
DECLARE
     view_name TEXT := '';
BEGIN
     view_name := $vn$
     CREATE MATERIALIZED VIEW schema.view_name_mv
     ( 
          "column1",
          "column2",
          "column3"
     )
     as 
     select 
          column1, 
          column2,
          column3
     from schema.table_name;
     $vn$;
END; 
$body$
     LANGUAGE 'plpgsql' VOLATILE;

有两种方法:

  1. 在创建物化视图后立即在函数中显式发出 GRANT 语句:

    GRANT SELECT ON "schema".view_name_mv TO appuser;
    
  2. 使用 ALTER DEFAULT PRIVILEGES 以便该架构中的任何未来表、视图和物化视图都获得用户的权限:

    ALTER DEFAULT PRIVILEGES FOR ROLE creator IN SCHEMA "schema"
       GRANT SELECT ON TABLES TO appuser;
    

    这里假定创建实体化视图的用户是creator

查看此内容后,我认为在某些情况下,您可能还需要进行函数调用,该函数调用以无权创建对象的用户身份在数据库中创建对象。因此,如果你想在一个函数中创建一个物化视图,而进行函数调用的用户权限有限,那么你可能想要区分一个函数是应该继承创建该函数的用户的权限,还是应该继承创建该函数的用户的权限对函数的调用。这可以按如下方式完成:

Security Invoker: 表示该函数将以调用它的用户的权限执行。这是默认值。

    CREATE OR REPLACE FUNCTION schema.my_function_si()
    RETURNS void AS $body$
    DECLARE
     view_name TEXT := '';
    BEGIN
     view_name := $vn$
    CREATE MATERIALIZED VIEW schema.view_name_mv
    ( 
          "column1",
          "column2",
          "column3"
    )
    as 
    select 
          column1, 
          column2,
          column3
    from schema.table_name;
    $vn$;
    END; 
    $body$
    LANGUAGE 'plpgsql' VOLATILE SECURITY INVOKER;

物化视图将继承调用用户的权限。

Security Definer: SECURITY DEFINER 指定函数将以创建它的用户的权限执行。

    CREATE OR REPLACE FUNCTION schema.my_function_sd()
    RETURNS void AS $body$
    DECLARE
     view_name TEXT := '';
    BEGIN
     view_name := $vn$
    CREATE MATERIALIZED VIEW schema.view_name_mv
    ( 
          "column1",
          "column2",
          "column3"
    )
    as 
    select 
          column1, 
          column2,
          column3
    from schema.table_name;
    $vn$;
    END; 
    $body$
    LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER;

实体化视图将继承创建函数的用户的权限。