@@ -515,7 +515,7 @@ func CreateGrant(ctx context.Context, d *schema.ResourceData, meta interface{})
515515 if err != nil {
516516 return diag .Errorf ("failed showing grants: %v" , err )
517517 }
518- if conflictingGrant != nil {
518+ if conflictingGrant != nil && areSameGrants ( grant , conflictingGrant ) {
519519 return diag .Errorf ("user/role %#v already has grant %v - " , grant .GetUserOrRole (), conflictingGrant )
520520 }
521521
@@ -816,6 +816,41 @@ func getMatchingGrant(ctx context.Context, db *sql.DB, desiredGrant MySQLGrant)
816816 return result , nil
817817}
818818
819+ func areSameGrants (grantA MySQLGrant , grantB MySQLGrant ) bool {
820+
821+ // If grants do not conflict (e.g. different users or databases), they are not the same
822+ if ! grantA .ConflictsWithGrant (grantB ) {
823+ return false
824+ }
825+
826+ // Compare privileges
827+ grantAWithPrivileges , aHasPrivileges := grantA .(MySQLGrantWithPrivileges )
828+ grantBWithPrivileges , bHasPrivileges := grantB .(MySQLGrantWithPrivileges )
829+ if aHasPrivileges && bHasPrivileges {
830+ privilegesA := normalizePerms (grantAWithPrivileges .GetPrivileges ())
831+ privilegesB := normalizePerms (grantBWithPrivileges .GetPrivileges ())
832+ if ! reflect .DeepEqual (privilegesA , privilegesB ) {
833+ return false
834+ }
835+ }
836+
837+ // Compare roles
838+ grantAWithRoles , aHasRoles := grantA .(MySQLGrantWithRoles )
839+ grantBWithRoles , bHasRoles := grantB .(MySQLGrantWithRoles )
840+ if aHasRoles && bHasRoles {
841+ rolesA := grantAWithRoles .GetRoles ()
842+ rolesB := grantBWithRoles .GetRoles ()
843+ sort .Strings (rolesA )
844+ sort .Strings (rolesB )
845+ if ! reflect .DeepEqual (rolesA , rolesB ) {
846+ return false
847+ }
848+ }
849+
850+ // If neither privileges nor roles are present, or both match, the grants are considered the same
851+ return true
852+ }
853+
819854var (
820855 kUserOrRoleRegex = regexp .MustCompile ("['`]?([^'`]+)['`]?(?:@['`]?([^'`]+)['`]?)?" )
821856)
0 commit comments