@@ -122,13 +122,12 @@ again:
122122 }
123123 goto tokenFoundLabel
124124 }
125- if strings .HasPrefix (s , "$__interval" ) {
126- lex .sTail = s [len ("$__interval" ):]
127- return "$__interval" , nil
128- }
129- if strings .HasPrefix (s , "$__rate_interval" ) {
130- lex .sTail = s [len ("$__rate_interval" ):]
131- return "$__interval" , nil
125+ if isVariable (s ) {
126+ token , err = scanVariable (s )
127+ if err != nil {
128+ return "" , err
129+ }
130+ goto tokenFoundLabel
132131 }
133132 return "" , fmt .Errorf ("cannot recognize %q" , s )
134133
@@ -301,6 +300,43 @@ func scanPositiveNumber(s string) (string, error) {
301300 return s [:j ], nil
302301}
303302
303+ func isVariable (s string ) bool {
304+ return len (s ) > 1 && s [0 ] == '$'
305+ }
306+
307+ func isVariableChar (c byte ) bool {
308+ return (c >= 'A' && c <= 'Z' ) || (c >= 'a' && c <= 'z' ) || (c >= '0' && c <= '9' ) || c == '_'
309+ }
310+
311+ func scanVariable (s string ) (string , error ) {
312+ if len (s ) < 2 {
313+ return "" , fmt .Errorf ("too small string for a variable %q" , s )
314+ }
315+ i := 1
316+ hasBraces := s [i ] == '{'
317+ if hasBraces {
318+ i ++
319+ }
320+ for i < len (s ) {
321+ if hasBraces {
322+ if s [i ] == '}' {
323+ i ++
324+ break
325+ }
326+ if ! isVariableChar (s [i ]) {
327+ return "" , fmt .Errorf ("not allowed symbol in variable %q" , s )
328+ }
329+ } else if ! isVariableChar (s [i ]) {
330+ break
331+ }
332+ i ++
333+ }
334+ if hasBraces && i <= 3 || i <= 2 {
335+ return "" , fmt .Errorf ("impossible variable name %q" , s )
336+ }
337+ return s [:i ], nil
338+ }
339+
304340func scanNumMultiplier (s string ) int {
305341 if len (s ) > 3 {
306342 s = s [:3 ]
@@ -534,7 +570,7 @@ func scanSpecialIntegerPrefix(s string) (skipChars int, isHex bool) {
534570}
535571
536572func isPositiveDuration (s string ) bool {
537- if s == "$__interval" {
573+ if s == "$__interval" || s == "$__rate_interval" {
538574 return true
539575 }
540576 n := scanDuration (s )
@@ -610,7 +646,7 @@ func DurationValue(s string, step int64) (int64, error) {
610646}
611647
612648func parseSingleDuration (s string , step int64 ) (float64 , error ) {
613- if s == "$__interval" {
649+ if s == "$__interval" || s == "$__rate_interval" {
614650 return float64 (step ), nil
615651 }
616652
@@ -676,8 +712,8 @@ func scanSingleDuration(s string, canBeNegative bool) int {
676712 if s [0 ] == '-' && canBeNegative {
677713 i ++
678714 }
679- if s [i :] == "$__interval" {
680- return i + len ("$__interval" )
715+ if s [i :] == "$__interval" || s [ i :] == "$__rate_interval" {
716+ return i + len (s [ i :] )
681717 }
682718 for i < len (s ) && isDecimalChar (s [i ]) {
683719 i ++
0 commit comments