복붙노트

[SQL] 나는 Redshift에에 보조금을 보는 방법

SQL

나는 Redshift에에 보조금을 보는 방법

나는 적색 편이에 보조금을보고 싶습니다.

나는 포스트 그레스이보기를 발견 :

CREATE OR REPLACE VIEW view_all_grants AS 
SELECT 
  use.usename as subject, 
  nsp.nspname as namespace, 
  c.relname as item, 
  c.relkind as type, 
  use2.usename as owner, 
  c.relacl, 
  (use2.usename != use.usename and c.relacl::text !~ ('({|,)' || use.usename || '=')) as public
FROM 
  pg_user use 
  cross join pg_class c 
  left join pg_namespace nsp on (c.relnamespace = nsp.oid) 
  left join pg_user use2 on (c.relowner = use2.usesysid)
WHERE 
  c.relowner = use.usesysid or 
  c.relacl::text ~ ('({|,)(|' || use.usename || ')=') 
ORDER BY 
  subject, 
  namespace, 
  item 

relacl의 :: 텍스트 캐스트가 다음에 실패하기 때문에 어떤 작동하지 않습니다 :

ERROR: cannot cast type aclitem[] to character varying [SQL State=42846] 

에 쿼리를 수정

CREATE OR REPLACE VIEW view_all_grants AS 
SELECT 
  use.usename as subject, 
  nsp.nspname as namespace, 
  c.relname as item, 
  c.relkind as type, 
  use2.usename as owner, 
  c.relacl 
  -- , (use2.usename != use.usename and c.relacl::text !~ ('({|,)' || use.usename || '=')) as public
FROM 
  pg_user use 
  cross join pg_class c 
  left join pg_namespace nsp on (c.relnamespace = nsp.oid) 
  left join pg_user use2 on (c.relowner = use2.usesysid)
WHERE 
  c.relowner = use.usesysid 
  -- or c.relacl::text ~ ('({|,)(|' || use.usename || ')=') 
ORDER BY 
  subject, 
  namespace, 
  item 

뷰가 생성 될,하지만이 모든 관련 데이터가 표시되지 않았는지 걱정 있습니다.

어떻게 적색 편이에 대한 작업에보기를 수정하거나 적색 편이에보기 보조금에 대한 더 나은 / 다른 방법이 할 수 있습니까?

UPDATE : Redshift에가 보조금을 확인하는 HAS_TABLE_PRIVILEGE 기능을 가지고 있습니다. (여기를 봐)

해결법

  1. ==============================

    1.또 다른 변화는 같은 수 :

    또 다른 변화는 같은 수 :

    SELECT * 
    FROM 
        (
        SELECT 
            schemaname
            ,objectname
            ,usename
            ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'select') AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS sel
            ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'insert') AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS ins
            ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'update') AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS upd
            ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'delete') AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS del
            ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'references') AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS ref
        FROM
            (
            SELECT schemaname, 't' AS obj_type, tablename AS objectname, schemaname + '.' + tablename AS fullobj FROM pg_tables
            WHERE schemaname not in ('pg_internal')
            UNION
            SELECT schemaname, 'v' AS obj_type, viewname AS objectname, schemaname + '.' + viewname AS fullobj FROM pg_views
            WHERE schemaname not in ('pg_internal')
            ) AS objs
            ,(SELECT * FROM pg_user) AS usrs
        ORDER BY fullobj
        )
    WHERE (sel = true or ins = true or upd = true or del = true or ref = true)
    and schemaname='<opt schema>'
    and usename = '<opt username>';
    
  2. ==============================

    2.오프 라인을 따라 뭔가 :

    오프 라인을 따라 뭔가 :

    select tablename, 
       HAS_TABLE_PRIVILEGE(tablename, 'select') as select,
       HAS_TABLE_PRIVILEGE(tablename, 'insert') as insert,
       HAS_TABLE_PRIVILEGE(tablename, 'update') as update,
       HAS_TABLE_PRIVILEGE(tablename, 'delete') as delete, 
       HAS_TABLE_PRIVILEGE(tablename, 'references') as references 
    from pg_tables where schemaname='public' order by tablename;
    

    나에게 모든 I 필요를 제공합니다.

  3. ==============================

    3.has_table_privilege 기능은 편리하지만 그룹을 관리 할 때 항상 관리에 도움이되지 않습니다. 나는 특정 사용자 나 그룹에 대한 보조금 스크립트를 만들 수있는 원래의 쿼리를 변신. 이 샘플 쿼리는 쉽게 사용자의 요구를 수용하기 위해 변신 할 수있다

    has_table_privilege 기능은 편리하지만 그룹을 관리 할 때 항상 관리에 도움이되지 않습니다. 나는 특정 사용자 나 그룹에 대한 보조금 스크립트를 만들 수있는 원래의 쿼리를 변신. 이 샘플 쿼리는 쉽게 사용자의 요구를 수용하기 위해 변신 할 수있다

    select namespace||'.'||item as tablename , 
    'grant ' || substring(
                    case when charindex('r',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',select ' else '' end 
                  ||case when charindex('w',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',update ' else '' end 
                  ||case when charindex('a',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',insert ' else '' end 
                  ||case when charindex('d',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',delete ' else '' end 
                  ||case when charindex('R',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',rule ' else '' end 
                  ||case when charindex('x',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',references ' else '' end 
                  ||case when charindex('t',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',trigger ' else '' end 
                  ||case when charindex('X',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',execute ' else '' end 
                  ||case when charindex('U',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',usage ' else '' end 
                  ||case when charindex('C',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',create ' else '' end 
                  ||case when charindex('T',split_part(split_part(array_to_string(relacl, '|'),'group dw_developers=',2 ) ,'/',1)) > 0 then ',temporary ' else '' end 
               , 2,10000)
     || ' on '||namespace||'.'||item ||' to group dw_developers;' as grantsql
    from 
    (SELECT 
      use.usename as subject, 
      nsp.nspname as namespace, 
      c.relname as item, 
      c.relkind as type, 
      use2.usename as owner, 
      c.relacl 
     FROM 
      pg_user use 
      cross join pg_class c 
      left join pg_namespace nsp on (c.relnamespace = nsp.oid) 
      left join pg_user use2 on (c.relowner = use2.usesysid)
     WHERE 
      c.relowner = use.usesysid  
      and  nsp.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
     ORDER BY 
      subject,   namespace,   item 
     ) where relacl is not null
     and array_to_string(relacl, '|') like '%group dw_developers%' order by 1
    
  4. ==============================

    4.mike_pdb I의 대답에 대한 개발은 다음과 함께했다

    mike_pdb I의 대답에 대한 개발은 다음과 함께했다

     WITH object_list(schema_name,object_name,permission_info)
     AS (
        SELECT N.nspname, C.relname, array_to_string(relacl,',')
        FROM pg_class AS C
            INNER JOIN pg_namespace AS N
            ON C.relnamespace = N.oid
        WHERE C.relkind in ('v','r')
        AND  N.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
        AND C.relacl[1] IS NOT NULL
      ),
      object_permissions(schema_name,object_name,permission_string)
      AS (
        SELECT schema_name,object_name, SPLIT_PART(permission_info,',',1) FROM object_list
        UNION ALL
        SELECT schema_name,object_name, SPLIT_PART(permission_info,',',2) FROM object_list
        UNION ALL
        SELECT schema_name,object_name, SPLIT_PART(permission_info,',',3) FROM object_list
        UNION ALL
        SELECT schema_name,object_name, SPLIT_PART(permission_info,',',4) FROM object_list
        UNION ALL
        SELECT schema_name,object_name, SPLIT_PART(permission_info,',',5) FROM object_list
        UNION ALL
        SELECT schema_name,object_name, SPLIT_PART(permission_info,',',6) FROM object_list
        UNION ALL
        SELECT schema_name,object_name, SPLIT_PART(permission_info,',',7) FROM object_list
        UNION ALL
        SELECT schema_name,object_name, SPLIT_PART(permission_info,',',8) FROM object_list
        UNION ALL
        SELECT schema_name,object_name, SPLIT_PART(permission_info,',',9) FROM object_list
        UNION ALL
        SELECT schema_name,object_name, SPLIT_PART(permission_info,',',10) FROM object_list
      ),
      permission_parts(schema_name, object_name,security_principal, permission_pattern)
      AS (
          SELECT
              schema_name,
              object_name,
              LEFT(permission_string ,CHARINDEX('=',permission_string)-1),
              SPLIT_PART(SPLIT_PART(permission_string,'=',2),'/',1)
          FROM object_permissions
          WHERE permission_string >''
      )
    SELECT
        schema_name,
        object_name,
        'GRANT ' ||
        SUBSTRING(
            case when charindex('r',permission_pattern) > 0 then ',SELECT ' else '' end
          ||case when charindex('w',permission_pattern) > 0 then ',UPDATE ' else '' end
          ||case when charindex('a',permission_pattern) > 0 then ',INSERT ' else '' end
          ||case when charindex('d',permission_pattern) > 0 then ',DELETE ' else '' end
          ||case when charindex('R',permission_pattern) > 0 then ',RULE ' else '' end
          ||case when charindex('x',permission_pattern) > 0 then ',REFERENCES ' else '' end
          ||case when charindex('t',permission_pattern) > 0 then ',TRIGGER ' else '' end
          ||case when charindex('X',permission_pattern) > 0 then ',EXECUTE ' else '' end
          ||case when charindex('U',permission_pattern) > 0 then ',USAGE ' else '' end
          ||case when charindex('C',permission_pattern) > 0 then ',CREATE ' else '' end
          ||case when charindex('T',permission_pattern) > 0 then ',TEMPORARY ' else '' end
        ,2,10000
        )
        || ' ON ' || schema_name||'.'||object_name
         || ' TO ' || security_principal
         || ';' as grantsql
    FROM permission_parts
    
    ;
    

    여기에 사용 된 3 공통 테이블 표현식이 있습니다.

    mike_pdb의 솔루션에 따라 개별 권한 문자는 보조금의 연결된 목록으로 변환됩니다. 우리가하지 않는 한 보조금은 우리가 목록의 첫 번째 쉼표를 폐기하는 위치 2에서 문자열 사용하십시오 사용될 것이다.

    당신은 스키마 권한 떨어져 스크립팅에 대해 정확히 같은 방법을 사용할 수 있습니다

    WITH schema_list(schema_name, permission_info)
    AS (
        SELECT nspname, array_to_string(nspacl,',')
        FROM pg_namespace
        WHERE nspacl[1] IS NOT NULL
        AND nspname NOT LIKE 'pg%' AND nspname NOT IN ('public','information_schema')
    ),
    schema_permissions(schema_name,permission_string)
    AS (
        SELECT schema_name,SPLIT_PART(permission_info,',',1) FROM schema_list
        UNION ALL
        SELECT schema_name,SPLIT_PART(permission_info,',',2) FROM schema_list
        UNION ALL
        SELECT schema_name,SPLIT_PART(permission_info,',',3) FROM schema_list
        UNION ALL
        SELECT schema_name,SPLIT_PART(permission_info,',',4) FROM schema_list
        UNION ALL
        SELECT schema_name,SPLIT_PART(permission_info,',',5) FROM schema_list
        UNION ALL
        SELECT schema_name,SPLIT_PART(permission_info,',',6) FROM schema_list
        UNION ALL
        SELECT schema_name,SPLIT_PART(permission_info,',',7) FROM schema_list
        UNION ALL
        SELECT schema_name,SPLIT_PART(permission_info,',',8) FROM schema_list
        UNION ALL
        SELECT schema_name,SPLIT_PART(permission_info,',',9) FROM schema_list
        UNION ALL
        SELECT schema_name,SPLIT_PART(permission_info,',',10) FROM schema_list
    ),
    permission_parts(schema_name, security_principal, permission_pattern)
    AS (
        SELECT
            schema_name,
            LEFT(permission_string ,CHARINDEX('=',permission_string)-1),
            SPLIT_PART(SPLIT_PART(permission_string,'=',2),'/',1)
        FROM schema_permissions
        WHERE permission_string >''
    )
    SELECT
        schema_name,
        'GRANT ' ||
        SUBSTRING(
            case when charindex('r',permission_pattern) > 0 then ',SELECT ' else '' end
          ||case when charindex('w',permission_pattern) > 0 then ',UPDATE ' else '' end
          ||case when charindex('a',permission_pattern) > 0 then ',INSERT ' else '' end
          ||case when charindex('d',permission_pattern) > 0 then ',DELETE ' else '' end
          ||case when charindex('R',permission_pattern) > 0 then ',RULE ' else '' end
          ||case when charindex('x',permission_pattern) > 0 then ',REFERENCES ' else '' end
          ||case when charindex('t',permission_pattern) > 0 then ',TRIGGER ' else '' end
          ||case when charindex('X',permission_pattern) > 0 then ',EXECUTE ' else '' end
          ||case when charindex('U',permission_pattern) > 0 then ',USAGE ' else '' end
          ||case when charindex('C',permission_pattern) > 0 then ',CREATE ' else '' end
          ||case when charindex('T',permission_pattern) > 0 then ',TEMPORARY ' else '' end
        ,2,10000
        )
        || ' ON SCHEMA ' || schema_name
         || ' TO ' || security_principal
         || ';' as grantsql
    FROM permission_parts;
    
  5. ==============================

    5.여기가 @drtf하여 위의 쿼리를 기반으로 만든 사용자가 스키마에보기 보조금에 또 다른 유용한 쿼리 (사용, 생성)입니다 :

    여기가 @drtf하여 위의 쿼리를 기반으로 만든 사용자가 스키마에보기 보조금에 또 다른 유용한 쿼리 (사용, 생성)입니다 :

    SELECT * 
    FROM 
        (
        SELECT 
            schemaname
            ,usename
            ,HAS_SCHEMA_PRIVILEGE(usrs.usename, schemaname, 'usage') AS usg
            ,HAS_SCHEMA_PRIVILEGE(usrs.usename, schemaname, 'create') AS crt
        FROM
            (
            SELECT distinct(schemaname) FROM pg_tables
            WHERE schemaname not in ('pg_internal')
            UNION
            SELECT distinct(schemaname) FROM pg_views
            WHERE schemaname not in ('pg_internal')
            ) AS objs
            ,(SELECT * FROM pg_user) AS usrs
        ORDER BY schemaname
        )
    WHERE (usg = true or crt = true)
    --and schemaname='<opt schemaname>'
    --and usename = '<opt username>';
    
  6. ==============================

    6.나는 이것을 많이 고생하고 마지막으로 내가보고 싶은 날을 제공하는 솔루션을 함께했다.

    나는 이것을 많이 고생하고 마지막으로 내가보고 싶은 날을 제공하는 솔루션을 함께했다.

    WITH tabledef as (
        SELECT schemaname,
            't' AS typename,
            tablename AS objectname,
            tableowner as owner,
            schemaname + '.' + tablename AS fullname
        FROM pg_tables
        UNION 
        SELECT schemaname,
            'v' AS typename,
            viewname AS objectname,
            viewowner as owner,
            schemaname + '.' + viewname AS fullname
        FROM pg_views
    ),
    res AS (
        SELECT t.*,
        CASE HAS_TABLE_PRIVILEGE(u.usename, t.fullname, 'select')
        WHEN true THEN u.usename
        ELSE NULL END AS sel,
        CASE HAS_TABLE_PRIVILEGE(u.usename, t.fullname, 'insert')
        WHEN true THEN u.usename
        ELSE NULL END AS ins,
        CASE HAS_TABLE_PRIVILEGE(u.usename, t.fullname, 'update')
        WHEN true THEN u.usename
        ELSE NULL END AS upd,
        CASE HAS_TABLE_PRIVILEGE(u.usename, t.fullname, 'delete')
        WHEN true THEN u.usename
        ELSE NULL END AS del,
        CASE HAS_TABLE_PRIVILEGE(u.usename, t.fullname, 'references')
        WHEN true THEN u.usename
        ELSE NULL END AS ref
        FROM tabledef AS t
        JOIN pg_user AS u
        ON HAS_TABLE_PRIVILEGE(u.usename, t.fullname, 'select') = true
            OR HAS_TABLE_PRIVILEGE(u.usename, t.fullname, 'insert') = true
            OR HAS_TABLE_PRIVILEGE(u.usename, t.fullname, 'update') = true
            OR HAS_TABLE_PRIVILEGE(u.usename, t.fullname, 'delete') = true
            OR HAS_TABLE_PRIVILEGE(u.usename, t.fullname, 'references') = true
            OR t.owner = u.usename
        WHERE t.schemaname = 'analytics'
    )
    SELECT schemaname, objectname, owner, sel, ins, upd, del, ref FROM res
    WHERE sel not in ('rdsdb', '<superuser>')
    ORDER BY schemaname, objectname;
    

    두 가지 중요한 라인 - 어떤 스키마 포인트 액세스를 검색하는 한

    WHERE t.schemaname = 'analytics'
    

    그리고 - 둘째 된 결과에서 폐기 수퍼 유저 권한 (그들은 어쨌든 완전한 권한이).

    WHERE sel not in ('rdsdb', '<superuser>')
    
  7. from https://stackoverflow.com/questions/18741334/how-do-i-view-grants-on-redshift by cc-by-sa and MIT license