From cec68ff98cce871fb771ce30530815135385c45c Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin <valyala@victoriametrics.com> Date: Thu, 5 Jan 2023 01:10:58 -0800 Subject: [PATCH] vendor: update github.com/VictoriaMetrics/metricsql from v0.50.0 to v0.51.0 Updates https://github.com/VictoriaMetrics/metricsql/pull/7 Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3589 --- app/vmselect/promql/exec_test.go | 2 +- docs/CHANGELOG.md | 1 + go.mod | 2 +- go.sum | 4 +- .../VictoriaMetrics/metricsql/lexer.go | 172 ++++++++++-------- vendor/modules.txt | 2 +- 6 files changed, 105 insertions(+), 78 deletions(-) diff --git a/app/vmselect/promql/exec_test.go b/app/vmselect/promql/exec_test.go index cef68ded1c..ff3d7cd874 100644 --- a/app/vmselect/promql/exec_test.go +++ b/app/vmselect/promql/exec_test.go @@ -7222,7 +7222,7 @@ func TestExecSuccess(t *testing.T) { }) t.Run(`rollup_scrape_interval()`, func(t *testing.T) { t.Parallel() - q := `sort_by_label(rollup_scrape_interval(1[5m:10s]), "rollup")` + q := `sort_by_label(rollup_scrape_interval(1[5M:10s]), "rollup")` r1 := netstorage.Result{ MetricName: metricNameExpected, Values: []float64{10, 10, 10, 10, 10, 10}, diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 767efcc4b0..8d1c9a24a2 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -15,6 +15,7 @@ The following tip changes can be tested by building VictoriaMetrics components f ## v1.79.x long-time support release (LTS) +* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): properly parse durations with uppercase suffixes such as `10S`, `5MS`, `1W`, etc. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3589). * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): [dockerswarm_sd_configs](https://docs.victoriametrics.com/sd_configs.html#dockerswarm_sd_configs): properly encode `filters` field. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3579) * BUGFIX: allow specifying values bigger than 2GiB to the following command-line flag values on 32-bit architectures (`386` and `arm`): `-storage.minFreeDiskSpaceBytes` and `-remoteWrite.maxDiskUsagePerURL`. Previously values bigger than 2GiB were incorrectly truncated on these architectures. * BUGFIX: [VictoriaMetrics enterprise](https://docs.victoriametrics.com/enterprise.html): expose proper values for `vm_downsampling_partitions_scheduled` and `vm_downsampling_partitions_scheduled_size_bytes` metrics, which were added at [v1.78.0](https://docs.victoriametrics.com/CHANGELOG.html#v1780). See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2612). diff --git a/go.mod b/go.mod index 64f77ce992..21f8af1186 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( // like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b github.com/VictoriaMetrics/fasthttp v1.1.0 github.com/VictoriaMetrics/metrics v1.23.0 - github.com/VictoriaMetrics/metricsql v0.50.0 + github.com/VictoriaMetrics/metricsql v0.51.1 github.com/aws/aws-sdk-go v1.44.157 github.com/cespare/xxhash/v2 v2.2.0 diff --git a/go.sum b/go.sum index e0ba77d68a..80277207b8 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,8 @@ github.com/VictoriaMetrics/fasthttp v1.1.0/go.mod h1:/7DMcogqd+aaD3G3Hg5kFgoFwlR github.com/VictoriaMetrics/metrics v1.18.1/go.mod h1:ArjwVz7WpgpegX/JpB0zpNF2h2232kErkEnzH1sxMmA= github.com/VictoriaMetrics/metrics v1.23.0 h1:WzfqyzCaxUZip+OBbg1+lV33WChDSu4ssYII3nxtpeA= github.com/VictoriaMetrics/metrics v1.23.0/go.mod h1:rAr/llLpEnAdTehiNlUxKgnjcOuROSzpw0GvjpEbvFc= -github.com/VictoriaMetrics/metricsql v0.50.0 h1:MCBhjn1qlfMqPGP6HiR9JgmEw7oTRGm/O8YwSeoaI1E= -github.com/VictoriaMetrics/metricsql v0.50.0/go.mod h1:6pP1ZeLVJHqJrHlF6Ij3gmpQIznSsgktEcZgsAWYel0= +github.com/VictoriaMetrics/metricsql v0.51.1 h1:gmh3ZGCDrqUTdhUrr87eJOXMOputDYs1PtLwTfySTsI= +github.com/VictoriaMetrics/metricsql v0.51.1/go.mod h1:6pP1ZeLVJHqJrHlF6Ij3gmpQIznSsgktEcZgsAWYel0= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= diff --git a/vendor/github.com/VictoriaMetrics/metricsql/lexer.go b/vendor/github.com/VictoriaMetrics/metricsql/lexer.go index c91f863811..c3aebd80d3 100644 --- a/vendor/github.com/VictoriaMetrics/metricsql/lexer.go +++ b/vendor/github.com/VictoriaMetrics/metricsql/lexer.go @@ -331,19 +331,22 @@ func scanNumMultiplier(s string) int { func scanIdent(s string) string { i := 0 for i < len(s) { - if isIdentChar(s[i]) { - i++ + r, size := utf8.DecodeRuneInString(s[i:]) + if i == 0 && isFirstIdentChar(r) || i > 0 && isIdentChar(r) { + i += size continue } - if s[i] != '\\' { + if r != '\\' { break } - i++ - - // Do not verify the next char, since it is escaped. - // The next char may be encoded as multi-byte UTF8 sequence. See https://en.wikipedia.org/wiki/UTF-8#Encoding - _, size := utf8.DecodeRuneInString(s[i:]) i += size + r, n := decodeEscapeSequence(s[i:]) + if r == utf8.RuneError { + // Invalid escape sequence + i -= size + break + } + i += n } if i == 0 { panic("BUG: scanIdent couldn't find a single ident char; make sure isIdentPrefix called before scanIdent") @@ -360,23 +363,12 @@ func unescapeIdent(s string) string { for { dst = append(dst, s[:n]...) s = s[n+1:] - if len(s) == 0 { - return string(dst) - } - if s[0] == 'x' && len(s) >= 3 { - h1 := fromHex(s[1]) - h2 := fromHex(s[2]) - if h1 >= 0 && h2 >= 0 { - dst = append(dst, byte((h1<<4)|h2)) - s = s[3:] - } else { - dst = append(dst, s[0]) - s = s[1:] - } + r, size := decodeEscapeSequence(s) + if r == utf8.RuneError { + // Cannot decode escape sequence. Put it in the output as is + dst = append(dst, '\\') } else { - // UTF8 char. See https://en.wikipedia.org/wiki/UTF-8#Encoding - _, size := utf8.DecodeRuneInString(s) - dst = append(dst, s[:size]...) + dst = utf8.AppendRune(dst, r) s = s[size:] } n = strings.IndexByte(s, '\\') @@ -387,49 +379,16 @@ func unescapeIdent(s string) string { } } -func fromHex(ch byte) int { - if ch >= '0' && ch <= '9' { - return int(ch - '0') - } - if ch >= 'a' && ch <= 'f' { - return int((ch - 'a') + 10) - } - if ch >= 'A' && ch <= 'F' { - return int((ch - 'A') + 10) - } - return -1 -} - -func toHex(n byte) byte { - if n < 10 { - return '0' + n - } - return 'a' + (n - 10) -} - func appendEscapedIdent(dst []byte, s string) []byte { - for i := 0; i < len(s); i++ { - ch := s[i] - if isIdentChar(ch) { - if i == 0 && !isFirstIdentChar(ch) { - // hex-encode the first char - dst = append(dst, '\\', 'x', toHex(ch>>4), toHex(ch&0xf)) - } else { - dst = append(dst, ch) - } - continue - } - - // escape ch - dst = append(dst, '\\') + i := 0 + for i < len(s) { r, size := utf8.DecodeRuneInString(s[i:]) - if r != utf8.RuneError && unicode.IsPrint(r) { - dst = append(dst, s[i:i+size]...) - i += size - 1 + if i == 0 && isFirstIdentChar(r) || i > 0 && isIdentChar(r) { + dst = utf8.AppendRune(dst, r) } else { - // hex-encode non-printable chars - dst = append(dst, 'x', toHex(ch>>4), toHex(ch&0xf)) + dst = appendEscapeSequence(dst, r) } + i += size } return dst } @@ -597,6 +556,7 @@ func DurationValue(s string, step int64) (int64, error) { } func parseSingleDuration(s string, step int64) (float64, error) { + s = strings.ToLower(s) numPart := s[:len(s)-1] if strings.HasSuffix(numPart, "m") { // Duration in ms @@ -656,6 +616,7 @@ func scanSingleDuration(s string, canBeNegative bool) int { if len(s) == 0 { return -1 } + s = strings.ToLower(s) i := 0 if s[0] == '-' && canBeNegative { i++ @@ -703,25 +664,26 @@ func isIdentPrefix(s string) bool { if len(s) == 0 { return false } - if s[0] == '\\' { - // Assume this is an escape char for the next char. - return true + r, size := utf8.DecodeRuneInString(s) + if r == '\\' { + r, _ = decodeEscapeSequence(s[size:]) + return r != utf8.RuneError } - return isFirstIdentChar(s[0]) + return isFirstIdentChar(r) } -func isFirstIdentChar(ch byte) bool { - if ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' { +func isFirstIdentChar(r rune) bool { + if unicode.IsLetter(r) { return true } - return ch == '_' || ch == ':' + return r == '_' || r == ':' } -func isIdentChar(ch byte) bool { - if isFirstIdentChar(ch) { +func isIdentChar(r rune) bool { + if isFirstIdentChar(r) { return true } - return isDecimalChar(ch) || ch == '.' + return r < 256 && isDecimalChar(byte(r)) || r == '.' } func isSpaceChar(ch byte) bool { @@ -732,3 +694,67 @@ func isSpaceChar(ch byte) bool { return false } } + +func appendEscapeSequence(dst []byte, r rune) []byte { + dst = append(dst, '\\') + if unicode.IsPrint(r) { + return utf8.AppendRune(dst, r) + } + // hex-encode non-printable chars + if r < 256 { + return append(dst, 'x', toHex(byte(r>>4)), toHex(byte(r&0xf))) + } + return append(dst, 'u', toHex(byte(r>>12)), toHex(byte((r>>8)&0xf)), toHex(byte(r>>4)), toHex(byte(r&0xf))) +} + +func decodeEscapeSequence(s string) (rune, int) { + if strings.HasPrefix(s, "x") || strings.HasPrefix(s, "X") { + if len(s) >= 3 { + h1 := fromHex(s[1]) + h2 := fromHex(s[2]) + if h1 >= 0 && h2 >= 0 { + r := rune((h1 << 4) | h2) + return r, 3 + } + } + return utf8.RuneError, 0 + } + if strings.HasPrefix(s, "u") || strings.HasPrefix(s, "U") { + if len(s) >= 5 { + h1 := fromHex(s[1]) + h2 := fromHex(s[2]) + h3 := fromHex(s[3]) + h4 := fromHex(s[4]) + if h1 >= 0 && h2 >= 0 && h3 >= 0 && h4 >= 0 { + return rune((h1 << 12) | (h2 << 8) | (h3 << 4) | h4), 5 + } + } + return utf8.RuneError, 0 + } + r, size := utf8.DecodeRuneInString(s) + if unicode.IsPrint(r) { + return r, size + } + // Improperly escaped non-printable char + return utf8.RuneError, 0 +} + +func fromHex(ch byte) int { + if ch >= '0' && ch <= '9' { + return int(ch - '0') + } + if ch >= 'a' && ch <= 'f' { + return int((ch - 'a') + 10) + } + if ch >= 'A' && ch <= 'F' { + return int((ch - 'A') + 10) + } + return -1 +} + +func toHex(n byte) byte { + if n < 10 { + return '0' + n + } + return 'a' + (n - 10) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index e6745dbe10..3f66334720 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -31,7 +31,7 @@ github.com/VictoriaMetrics/fasthttp/stackless # github.com/VictoriaMetrics/metrics v1.23.0 ## explicit; go 1.15 github.com/VictoriaMetrics/metrics -# github.com/VictoriaMetrics/metricsql v0.50.0 +# github.com/VictoriaMetrics/metricsql v0.51.1 ## explicit; go 1.13 github.com/VictoriaMetrics/metricsql github.com/VictoriaMetrics/metricsql/binaryop