@@ -32,10 +32,12 @@ var (
3232
3333 // Regex Pattern to match GTID tags
3434 // Tag must start with a letter e.g. tag1 in uuid:tag1:1-5
35- tagRegex = regexp .MustCompile ("^[a-z_][a-z0-9_]{0,31}" )
35+ tagRegex = regexp .MustCompile ("^[a-z_][a-z0-9_]{0,31}$ " )
3636)
3737
38- type TagInterval struct {
38+ // The below struct represents a tagged interval in GTID set.
39+ // It is private and should not be exported outside this package.
40+ type tagInterval struct {
3941 Tag string // tag name
4042 Interval []string // intervals
4143}
@@ -51,7 +53,7 @@ type TagInterval struct {
5153type OracleGtidSetEntry struct {
5254 UUID string
5355 DefaultIv string // default (untagged) interval
54- TaggedIv []TagInterval // tagged intervals
56+ TaggedIv []tagInterval // tagged intervals
5557}
5658
5759func ParseOracleGtidSetEntry (gtidRangeString string ) (* OracleGtidSetEntry , error ) {
@@ -78,61 +80,54 @@ func ParseOracleGtidSetEntry(gtidRangeString string) (*OracleGtidSetEntry, error
7880 // Split the non-UUID parts into multiple blocks
7981 s := strings .SplitN (gtid_str [1 ], ":" , - 1 )
8082
81- // Initialize the tag and interval
82- var default_iv string // Default interval
83- var tag_ivs []TagInterval // Full tagged interval
84- var ti TagInterval // Current tag interval
83+ var default_iv string // Default interval
84+ var tag_ivs []tagInterval // Full tagged interval
85+ var tip * tagInterval = nil // Current tag interval
8586
87+ // Tagged intervals always follow untagged ones
88+ // so once tip != nil it will never be nil again
8689 for i := range s {
87-
8890 // If it is a GTID tag
8991 if tagRegex .MatchString (s [i ]) {
90-
91- if (ti .Tag != "" ) && (len (ti .Interval ) == 0 ) {
92+ if tip != nil && (tip .Tag != "" ) && (len (tip .Interval ) == 0 ) {
9293 // If the tag is already set and we got another tag
93- return nil , fmt .Errorf ("Invalid format" )
94- } else if ( ti .Tag == "" ) && (len (ti .Interval ) != 0 ) {
95- // If the tag is not set and we already have the interval set
94+ return nil , fmt .Errorf ("Invalid format: Found a tag without any intervals " )
95+ } else if tip != nil && ( tip .Tag == "" ) && (len (tip .Interval ) != 0 ) {
96+ // Should never happen - just in case
9697 return nil , fmt .Errorf ("Invalid format" )
9798 } else {
9899 // Now process the new tag
99- ti . Tag = s [ i ]
100- // Reset iv for the current tag
101- ti . Interval = nil
100+ ti := tagInterval {
101+ Tag : s [ i ],
102+ }
102103 // Append the new tag to tag_ivs
103104 tag_ivs = append (tag_ivs , ti )
105+ tip = & tag_ivs [len (tag_ivs )- 1 ]
104106 }
105107 } else {
106- // If it is an GTID interval
108+ // If it is a GTID interval
107109 if singleValueInterval .MatchString (s [i ]) || multiValueInterval .MatchString (s [i ]) {
108110 // If it is an empty tag, add it to default interval
109- if len ( ti . Tag ) == 0 {
111+ if tip == nil {
110112 default_iv += ":" + s [i ]
111113 } else {
112114 // If tag is already set, add it to the tag interval
113- ti .Interval = append (ti .Interval , s [i ])
114- tag_ivs [len (tag_ivs )- 1 ].Interval = append (tag_ivs [len (tag_ivs )- 1 ].Interval , s [i ])
115+ tip .Interval = append (tip .Interval , s [i ])
115116 }
116117 } else {
117118 // Regex failed, invalid format
118119 return nil , fmt .Errorf ("Invalid format" )
119120 }
120121 }
121122 }
122-
123123 // If the interval of the last tag is empty, then it is an invalid format
124124 // eg: "UUID:1-5139::tag1:"
125- if ( ti .Tag != "" ) && (len (tag_ivs [ len ( tag_ivs ) - 1 ] .Interval ) == 0 ) {
126- return nil , fmt .Errorf ("Invalid format" )
125+ if tip != nil && ( tip .Tag != "" ) && (len (tip .Interval ) == 0 ) {
126+ return nil , fmt .Errorf ("Invalid format: Found a tag without any intervals " )
127127 }
128-
129128 // Don't append ':' for the first interval in the default set
130- if len (default_iv ) != 0 {
131- default_iv , _ = strings .CutPrefix (default_iv , ":" )
132- }
133-
129+ default_iv , _ = strings .CutPrefix (default_iv , ":" )
134130 entry := OracleGtidSetEntry {UUID : uuid , DefaultIv : default_iv , TaggedIv : tag_ivs }
135-
136131 return & entry , nil
137132}
138133
@@ -222,21 +217,21 @@ func (this *OracleGtidSetEntry) Explode() (result [](*OracleGtidSetEntry)) {
222217 intervalEnd , _ := strconv .Atoi (submatch [2 ])
223218 for i := intervalStart ; i <= intervalEnd ; i ++ {
224219
225- ti := TagInterval {
220+ ti := tagInterval {
226221 Tag : tag ,
227222 Interval : []string {fmt .Sprintf ("%d" , i )}}
228- taggedIv := []TagInterval {ti }
223+ taggedIv := []tagInterval {ti }
229224
230225 entry := OracleGtidSetEntry {UUID : this .UUID , TaggedIv : taggedIv }
231226 result = append (result , & entry )
232227 }
233228 } else if submatch := singleValueInterval .FindStringSubmatch (interval ); submatch != nil {
234229
235230 // Single-value interval
236- ti := TagInterval {
231+ ti := tagInterval {
237232 Tag : tag ,
238233 Interval : []string {interval }}
239- taggedIv := []TagInterval {ti }
234+ taggedIv := []tagInterval {ti }
240235
241236 entry := OracleGtidSetEntry {UUID : this .UUID , TaggedIv : taggedIv }
242237 result = append (result , & entry )
0 commit comments