@@ -169,6 +169,10 @@ func resourceRedshiftGrantReadImpl(db *DBConnection, d *schema.ResourceData) err
169169 switch objectType {
170170 case "database" :
171171 return readGroupDatabaseGrants (db , d )
172+ case "schema" :
173+ return readGroupSchemaGrants (db , d )
174+ case "table" :
175+ return readGroupTableGrants (db , d )
172176 default :
173177 return fmt .Errorf ("Unsupported %s %s" , grantObjectTypeAttr , objectType )
174178 }
@@ -203,48 +207,99 @@ func readGroupDatabaseGrants(db *DBConnection, d *schema.ResourceData) error {
203207 return nil
204208}
205209
206- func readGroupGrantsForTables (tx * sql.Tx , groupName , schemaName string , tablesNames []string ) ([]string , error ) {
207- var tables , tableSelect , tableUpdate , tableInsert , tableDelete , tableReferences int
210+ func readGroupSchemaGrants (db * DBConnection , d * schema.ResourceData ) error {
211+ groupName := d .Get (grantGroupAttr ).(string )
212+ schemaName := d .Get (grantSchemaAttr ).(string )
213+
214+ var schemaCreate , schemaUsage bool
215+
208216 query := `
209217 SELECT
210- nvl(count(cl.relname), 0) tables,
211- nvl(sum(decode(charindex('r',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)), 0,0,1)), 0) as select,
212- nvl(sum(decode(charindex('w',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)), 0,0,1)), 0) as update,
213- nvl(sum(decode(charindex('a',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)), 0,0,1)), 0) as insert,
214- nvl(sum(decode(charindex('d',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)), 0,0,1)), 0) as delete,
215- nvl(sum(decode(charindex('x',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)), 0,0,1)), 0) as references
216- FROM pg_class cl
217- JOIN pg_group gr ON array_to_string(cl.relacl, '|') LIKE '%group '||gr.groname||'=%'
218- JOIN pg_namespace nsp ON nsp.oid = cl.relnamespace
218+ decode(charindex('C',split_part(split_part(array_to_string(ns.nspacl, '|'),gr.groname,2 ) ,'/',1)), 0,0,1) as create,
219+ decode(charindex('U',split_part(split_part(array_to_string(ns.nspacl, '|'),gr.groname,2 ) ,'/',1)), 0,0,1) as usage
220+ FROM pg_namespace ns, pg_group gr
219221 WHERE
220- cl.relkind = 'r'
221- AND gr.groname=$1
222- AND nsp.nspname=$2
222+ ns.nspname=$1
223+ AND gr.groname=$2
223224`
224225
225- var err error = nil
226- if len (tablesNames ) > 0 {
227- query = fmt .Sprintf ("%s AND cl.relname = ANY($3)" , query )
228- err = tx .QueryRow (query , groupName , schemaName , pq .Array (tablesNames )).Scan (tables , tableSelect , tableUpdate , tableInsert , tableDelete , tableReferences )
229- } else {
230- err = tx .QueryRow (query , groupName , schemaName ).Scan (tableSelect , tableUpdate , tableInsert , tableDelete , tableReferences )
226+ if err := db .QueryRow (query , schemaName , groupName ).Scan (& schemaCreate , & schemaUsage ); err != nil {
227+ return err
231228 }
232229
230+ privileges := []string {}
231+ appendIfTrue (schemaCreate , "create" , & privileges )
232+ appendIfTrue (schemaUsage , "usage" , & privileges )
233+
234+ log .Printf ("[DEBUG] Collected schema '%s' privileges for group %s: %v" , schemaName , groupName , privileges )
235+
236+ d .Set (grantPrivilegesAttr , privileges )
237+
238+ return nil
239+ }
240+
241+ func readGroupTableGrants (db * DBConnection , d * schema.ResourceData ) error {
242+ query := `
243+ SELECT
244+ relname,
245+ decode(charindex('r',split_part(split_part(array_to_string(relacl, '|'),gr.groname,2 ) ,'/',1)), 0,0,1) as select,
246+ decode(charindex('w',split_part(split_part(array_to_string(relacl, '|'),gr.groname,2 ) ,'/',1)), 0,0,1) as update,
247+ decode(charindex('a',split_part(split_part(array_to_string(relacl, '|'),gr.groname,2 ) ,'/',1)), 0,0,1) as insert,
248+ decode(charindex('d',split_part(split_part(array_to_string(relacl, '|'),gr.groname,2 ) ,'/',1)), 0,0,1) as delete,
249+ decode(charindex('x',split_part(split_part(array_to_string(relacl, '|'),gr.groname,2 ) ,'/',1)), 0,0,1) as references
250+ FROM pg_group gr, pg_class cl
251+ JOIN pg_namespace nsp ON nsp.oid = cl.relnamespace
252+ WHERE
253+ cl.relkind = $1
254+ AND gr.groname=$2
255+ AND nsp.nspname=$3
256+ `
257+
258+ groupName := d .Get (grantGroupAttr ).(string )
259+ schemaName := d .Get (grantSchemaAttr ).(string )
260+ objects := d .Get (grantObjectsAttr ).(* schema.Set )
261+
262+ rows , err := db .Query (query , grantObjectTypesCodes ["table" ], groupName , schemaName )
233263 if err != nil {
234- return [] string {}, fmt . Errorf ( "failed to collect group privileges: %w" , err )
264+ return err
235265 }
236266
237- privileges := []string {}
238- expectedPrivileges := len (tablesNames )
239- appendIfTrue (tableSelect == expectedPrivileges , "select" , & privileges )
240- appendIfTrue (tableUpdate == expectedPrivileges , "update" , & privileges )
241- appendIfTrue (tableInsert == expectedPrivileges , "insert" , & privileges )
242- appendIfTrue (tableDelete == expectedPrivileges , "delete" , & privileges )
243- appendIfTrue (tableReferences == expectedPrivileges , "references" , & privileges )
267+ for rows .Next () {
268+ var objName string
269+ var tableSelect , tableUpdate , tableInsert , tableDelete , tableReferences bool
270+
271+ if err := rows .Scan (& objName , & tableSelect , & tableUpdate , & tableInsert , & tableDelete , & tableReferences ); err != nil {
272+ return err
273+ }
274+
275+ if objects .Len () > 0 && ! objects .Contains (objName ) {
276+ continue
277+ }
278+
279+ privilegesSet := schema .NewSet (schema .HashString , nil )
280+ if tableSelect {
281+ privilegesSet .Add ("select" )
282+ }
283+ if tableUpdate {
284+ privilegesSet .Add ("update" )
285+ }
286+ if tableInsert {
287+ privilegesSet .Add ("insert" )
288+ }
289+ if tableDelete {
290+ privilegesSet .Add ("delete" )
291+ }
292+ if tableReferences {
293+ privilegesSet .Add ("references" )
294+ }
244295
245- log .Printf ("[DEBUG] Collected privileges for group %s: %v\n " , groupName , privileges )
296+ if ! privilegesSet .Equal (d .Get (grantPrivilegesAttr ).(* schema.Set )) {
297+ d .Set (grantPrivilegesAttr , privilegesSet )
298+ break
299+ }
300+ }
246301
247- return privileges , nil
302+ return nil
248303}
249304
250305func revokeGroupGrants (tx * sql.Tx , databaseName string , d * schema.ResourceData ) error {
0 commit comments