@@ -207,31 +207,61 @@ type UUIDSet struct {
207207 Intervals IntervalSlice
208208}
209209
210- func ParseUUIDSet (str string ) (* UUIDSet , error ) {
211- str = strings .TrimSpace (str )
212- sep := strings .Split (str , ":" )
213- if len (sep ) < 2 {
214- return nil , errors .Errorf ("invalid GTID format, must UUID:interval[:interval]" )
215- }
216-
217- var err error
218- s := new (UUIDSet )
219- if s .SID , err = uuid .Parse (sep [0 ]); err != nil {
220- return nil , errors .Trace (err )
221- }
222-
223- // Handle interval
224- for i := 1 ; i < len (sep ); i ++ {
225- if in , err := parseInterval (sep [i ]); err != nil {
226- return nil , errors .Trace (err )
227- } else {
228- s .Intervals = append (s .Intervals , in )
229- }
230- }
231-
232- s .Intervals = s .Intervals .Normalize ()
233-
234- return s , nil
210+ // ParseUUIDSet parses a GTID set string into a map of UUIDSet structs keyed by their SID.
211+ // Supports multi-UUID sets like "uuid1:1-10,uuid2:5-15".
212+ func ParseUUIDSet (s string ) (map [string ]* UUIDSet , error ) {
213+ if s == "" {
214+ return nil , nil
215+ }
216+
217+ uuidSets := strings .Split (strings .TrimSpace (s ), "," )
218+ if len (uuidSets ) == 0 {
219+ return nil , fmt .Errorf ("empty UUID set" )
220+ }
221+
222+ result := make (map [string ]* UUIDSet )
223+ for _ , set := range uuidSets {
224+ set = strings .TrimSpace (set )
225+ if set == "" {
226+ continue
227+ }
228+
229+ parts := strings .SplitN (set , ":" , 2 )
230+ if len (parts ) != 2 {
231+ return nil , fmt .Errorf ("invalid UUID set format: %s" , set )
232+ }
233+
234+ sid , err := uuid .Parse (parts [0 ])
235+ if err != nil {
236+ return nil , fmt .Errorf ("invalid UUID: %s" , parts [0 ])
237+ }
238+
239+ // Check if this SID already exists in the map
240+ uuidSet , exists := result [sid .String ()]
241+ if ! exists {
242+ uuidSet = & UUIDSet {SID : sid }
243+ result [sid .String ()] = uuidSet
244+ }
245+
246+ intervals := strings .Split (parts [1 ], ":" )
247+ for _ , intervalStr := range intervals {
248+ interval , err := parseInterval (intervalStr )
249+ if err != nil {
250+ return nil , fmt .Errorf ("invalid interval in UUID set %s: %v" , set , err )
251+ }
252+ uuidSet .Intervals = append (uuidSet .Intervals , interval )
253+ }
254+
255+ if len (uuidSet .Intervals ) == 0 {
256+ return nil , fmt .Errorf ("no valid intervals in UUID set: %s" , set )
257+ }
258+ uuidSet .Intervals = uuidSet .Intervals .Normalize () // Normalize intervals after adding
259+ }
260+
261+ if len (result ) == 0 {
262+ return nil , fmt .Errorf ("no valid UUID sets parsed from: %s" , s )
263+ }
264+ return result , nil
235265}
236266
237267func NewUUIDSet (sid uuid.UUID , in ... Interval ) * UUIDSet {
@@ -398,23 +428,20 @@ type MysqlGTIDSet struct {
398428var _ GTIDSet = & MysqlGTIDSet {}
399429
400430func ParseMysqlGTIDSet (str string ) (GTIDSet , error ) {
401- s := new (MysqlGTIDSet )
402- s .Sets = make (map [string ]* UUIDSet )
403- if str == "" {
404- return s , nil
405- }
406-
407- sp := strings .Split (str , "," )
408-
409- // todo, handle redundant same uuid
410- for i := 0 ; i < len (sp ); i ++ {
411- if set , err := ParseUUIDSet (sp [i ]); err != nil {
412- return nil , errors .Trace (err )
413- } else {
414- s .AddSet (set )
415- }
416- }
417- return s , nil
431+ s := new (MysqlGTIDSet )
432+ s .Sets = make (map [string ]* UUIDSet )
433+ if str == "" {
434+ return s , nil
435+ }
436+
437+ sets , err := ParseUUIDSet (str ) // Use the updated ParseUUIDSet
438+ if err != nil {
439+ return nil , errors .Trace (err )
440+ }
441+ for sid , set := range sets {
442+ s .Sets [sid ] = set
443+ }
444+ return s , nil
418445}
419446
420447func DecodeMysqlGTIDSet (data []byte ) (* MysqlGTIDSet , error ) {
0 commit comments