@@ -344,6 +344,15 @@ func quoteIdentifier(id string) string {
344344 return `"` + esc + `"`
345345}
346346
347+ // quoteObjectName quotes each part of a dot-separated object name (e.g., DB.SCHEMA.TABLE)
348+ func quoteObjectName (objectName string ) string {
349+ parts := strings .Split (objectName , "." )
350+ for i , part := range parts {
351+ parts [i ] = quoteIdentifier (part )
352+ }
353+ return strings .Join (parts , "." )
354+ }
355+
347356func (rp * RoleProcessor ) createRoleIfNotExists () error {
348357 createRoleQuery := "CREATE ROLE IF NOT EXISTS " + rp .qRole
349358 if err := rp .execQuery (createRoleQuery ); err != nil {
@@ -1153,12 +1162,12 @@ func (rp *RoleProcessor) fetchCurrentGrants() map[GrantKey]struct{} {
11531162
11541163// Build GRANT statement from GrantKey
11551164func (rp * RoleProcessor ) buildGrantStatement (g GrantKey ) string {
1156- return fmt .Sprintf ("GRANT %s ON %s %s TO ROLE %s" , g .Privilege , g .ObjectType , g .ObjectName , rp .qRole )
1165+ return fmt .Sprintf ("GRANT %s ON %s %s TO ROLE %s" , g .Privilege , g .ObjectType , quoteObjectName ( g .ObjectName ) , rp .qRole )
11571166}
11581167
11591168// Build REVOKE statement from GrantKey
11601169func (rp * RoleProcessor ) buildRevokeQuery (g GrantKey ) string {
1161- return fmt .Sprintf ("REVOKE %s ON %s %s FROM ROLE %s" , g .Privilege , g .ObjectType , g .ObjectName , rp .qRole )
1170+ return fmt .Sprintf ("REVOKE %s ON %s %s FROM ROLE %s" , g .Privilege , g .ObjectType , quoteObjectName ( g .ObjectName ) , rp .qRole )
11621171}
11631172
11641173// Main sync logic
0 commit comments