mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vendor: update github.com/VictoriaMetrics/metricsql from v0.72.1 to v0.73.0
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5383
This commit is contained in:
parent
149d83e596
commit
2e30842582
7 changed files with 377 additions and 122 deletions
|
@ -30,9 +30,11 @@ See also [LTS releases](https://docs.victoriametrics.com/LTS-releases.html).
|
|||
|
||||
## tip
|
||||
|
||||
* FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): propagate [label filters](https://docs.victoriametrics.com/keyconcepts/#filtering) via all the [label manipulation functions](https://docs.victoriametrics.com/metricsql/#label-manipulation-functions). For example, `label_del(some_metric{job="foo"}, "instance") + other_metric{pod="bar"}` is now transformed to `label_del(some_metric{job="foo",pod="bar"}, "instance") + other_metric{job="foo",pod="bar"}`. This should reduce the amounts of time series processed during query execution.
|
||||
* FEATURE: [Single-node VictoriaMetrics](https://docs.victoriametrics.com/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): expose `vm_last_partition_parts` [metrics](https://docs.victoriametrics.com/#monitoring), which show the number of [parts in the latest partition](https://docs.victoriametrics.com/#storage). These metrics may help debugging query performance slowdown related to the increased number of parts in the last partition, since usually all the ingested data is written to the last partition and all the queries are performed over the recently ingested data, e.g. the last partition.
|
||||
* FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): support client-side TLS configuration for [InfluxDB](https://docs.victoriametrics.com/vmctl/#migrating-data-from-influxdb-1x). See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5748). Thanks to @khushijain21 for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5783).
|
||||
* FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): support client-side TLS configuration for [Remote Read protocol](https://docs.victoriametrics.com/vmctl/#migrating-data-by-remote-read-protocol). See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5748). Thanks to @khushijain21 for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5798).
|
||||
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): preserve [`WITH` templates](https://play.victoriametrics.com/select/accounting/1/6a716b0f-38bc-4856-90ce-448fd713e3fe/expand-with-exprs) when clicking the `prettify query` button at the right side of query input field. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5383).
|
||||
|
||||
* BUGFIX: fix the misleading error `0ms is out of allowed range [0 ...` when passing `step=0` to [/api/v1/query](https://docs.victoriametrics.com/keyconcepts/#instant-query)
|
||||
or [/api/v1/query_range](https://docs.victoriametrics.com/keyconcepts/#range-query). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5795).
|
||||
|
|
2
go.mod
2
go.mod
|
@ -9,7 +9,7 @@ require (
|
|||
github.com/VictoriaMetrics/easyproto v0.1.4
|
||||
github.com/VictoriaMetrics/fastcache v1.12.2
|
||||
github.com/VictoriaMetrics/metrics v1.32.0
|
||||
github.com/VictoriaMetrics/metricsql v0.72.1
|
||||
github.com/VictoriaMetrics/metricsql v0.73.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.25.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.0
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -71,8 +71,8 @@ github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkT
|
|||
github.com/VictoriaMetrics/metrics v1.24.0/go.mod h1:eFT25kvsTidQFHb6U0oa0rTrDRdz4xTYjpL8+UPohys=
|
||||
github.com/VictoriaMetrics/metrics v1.32.0 h1:r9JK2zndYv0TIxFXLEHwhQqRdnu8/O3cwJiCBX4vJCM=
|
||||
github.com/VictoriaMetrics/metrics v1.32.0/go.mod h1:r7hveu6xMdUACXvB8TYdAj8WEsKzWB0EkpJN+RDtOf8=
|
||||
github.com/VictoriaMetrics/metricsql v0.72.1 h1:fLIHgzezXgD4NjY5ksF4lRkHILW88uI5Lz0Q+N2ucnY=
|
||||
github.com/VictoriaMetrics/metricsql v0.72.1/go.mod h1:k4UaP/+CjuZslIjd+kCigNG9TQmUqh5v0TP/nMEy90I=
|
||||
github.com/VictoriaMetrics/metricsql v0.73.0 h1:MvYnUIZHWD+Kj+sKuBSI1asR1fw1BxQPGshs32C7FIk=
|
||||
github.com/VictoriaMetrics/metricsql v0.73.0/go.mod h1:k4UaP/+CjuZslIjd+kCigNG9TQmUqh5v0TP/nMEy90I=
|
||||
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
||||
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
|
|
211
vendor/github.com/VictoriaMetrics/metricsql/optimizer.go
generated
vendored
211
vendor/github.com/VictoriaMetrics/metricsql/optimizer.go
generated
vendored
|
@ -82,14 +82,24 @@ func getCommonLabelFilters(e Expr) []LabelFilter {
|
|||
case *RollupExpr:
|
||||
return getCommonLabelFilters(t.Expr)
|
||||
case *FuncExpr:
|
||||
if strings.ToLower(t.Name) == "label_set" {
|
||||
switch strings.ToLower(t.Name) {
|
||||
case "label_set":
|
||||
return getCommonLabelFiltersForLabelSet(t.Args)
|
||||
case "label_replace", "label_join", "label_map", "label_match", "label_mismatch", "label_transform":
|
||||
return getCommonLabelFiltersForLabelReplace(t.Args)
|
||||
case "label_copy", "label_move":
|
||||
return getCommonLabelFiltersForLabelCopy(t.Args)
|
||||
case "label_del", "label_uppercase", "label_lowercase", "labels_equal":
|
||||
return getCommonLabelFiltersForLabelDel(t.Args)
|
||||
case "label_keep":
|
||||
return getCommonLabelFiltersForLabelKeep(t.Args)
|
||||
default:
|
||||
arg := getFuncArgForOptimization(t.Name, t.Args)
|
||||
if arg == nil {
|
||||
return nil
|
||||
}
|
||||
return getCommonLabelFilters(arg)
|
||||
}
|
||||
arg := getFuncArgForOptimization(t.Name, t.Args)
|
||||
if arg == nil {
|
||||
return nil
|
||||
}
|
||||
return getCommonLabelFilters(arg)
|
||||
case *AggrFuncExpr:
|
||||
args := t.Args
|
||||
if len(args) > 0 && canAcceptMultipleArgsForAggrFunc(t.Name) {
|
||||
|
@ -164,6 +174,49 @@ func getCommonLabelFilters(e Expr) []LabelFilter {
|
|||
}
|
||||
}
|
||||
|
||||
func getCommonLabelFiltersForLabelKeep(args []Expr) []LabelFilter {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
lfs := getCommonLabelFilters(args[0])
|
||||
lfs = keepLabelFiltersForLabelNames(lfs, args[1:])
|
||||
return lfs
|
||||
}
|
||||
|
||||
func getCommonLabelFiltersForLabelDel(args []Expr) []LabelFilter {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
lfs := getCommonLabelFilters(args[0])
|
||||
lfs = dropLabelFiltersForLabelNames(lfs, args[1:])
|
||||
return lfs
|
||||
}
|
||||
|
||||
func getCommonLabelFiltersForLabelCopy(args []Expr) []LabelFilter {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
lfs := getCommonLabelFilters(args[0])
|
||||
args = args[1:]
|
||||
var labelNames []Expr
|
||||
for i := 0; i < len(args); i += 2 {
|
||||
if i+1 >= len(args) {
|
||||
return nil
|
||||
}
|
||||
labelNames = append(labelNames, args[i+1])
|
||||
}
|
||||
lfs = dropLabelFiltersForLabelNames(lfs, labelNames)
|
||||
return lfs
|
||||
}
|
||||
|
||||
func getCommonLabelFiltersForLabelReplace(args []Expr) []LabelFilter {
|
||||
if len(args) < 2 {
|
||||
return nil
|
||||
}
|
||||
lfs := getCommonLabelFilters(args[0])
|
||||
return dropLabelFiltersForLabelName(lfs, args[1])
|
||||
}
|
||||
|
||||
func getCommonLabelFiltersForLabelSet(args []Expr) []LabelFilter {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
|
@ -190,13 +243,8 @@ func getCommonLabelFiltersForLabelSet(args []Expr) []LabelFilter {
|
|||
continue
|
||||
}
|
||||
|
||||
lfsDst := lfs[:0]
|
||||
for _, lf := range lfs {
|
||||
if lf.Label != seLabelName.S {
|
||||
lfsDst = append(lfsDst, lf)
|
||||
}
|
||||
}
|
||||
lfs = append(lfsDst, LabelFilter{
|
||||
lfs = dropLabelFiltersForLabelName(lfs, labelName)
|
||||
lfs = append(lfs, LabelFilter{
|
||||
Label: seLabelName.S,
|
||||
Value: seLabelValue.S,
|
||||
})
|
||||
|
@ -288,11 +336,18 @@ func pushdownBinaryOpFiltersInplace(e Expr, lfs []LabelFilter) {
|
|||
case *RollupExpr:
|
||||
pushdownBinaryOpFiltersInplace(t.Expr, lfs)
|
||||
case *FuncExpr:
|
||||
if strings.ToLower(t.Name) == "label_set" && len(t.Args) > 0 {
|
||||
arg := t.Args[0]
|
||||
lfs = getPushdownLabelFiltersForLabelSet(t.Args[1:], lfs)
|
||||
pushdownBinaryOpFiltersInplace(arg, lfs)
|
||||
} else {
|
||||
switch strings.ToLower(t.Name) {
|
||||
case "label_set":
|
||||
pushdownLabelFiltersForLabelSet(t.Args, lfs)
|
||||
case "label_replace", "label_join", "label_map", "label_match", "label_mismatch", "label_transform":
|
||||
pushdownLabelFiltersForLabelReplace(t.Args, lfs)
|
||||
case "label_copy", "label_move":
|
||||
pushdownLabelFiltersForLabelCopy(t.Args, lfs)
|
||||
case "label_del", "label_uppercase", "label_lowercase", "labels_equal":
|
||||
pushdownLabelFiltersForLabelDel(t.Args, lfs)
|
||||
case "label_keep":
|
||||
pushdownLabelFiltersForLabelKeep(t.Args, lfs)
|
||||
default:
|
||||
arg := getFuncArgForOptimization(t.Name, t.Args)
|
||||
if arg != nil {
|
||||
pushdownBinaryOpFiltersInplace(arg, lfs)
|
||||
|
@ -318,24 +373,59 @@ func pushdownBinaryOpFiltersInplace(e Expr, lfs []LabelFilter) {
|
|||
}
|
||||
}
|
||||
|
||||
func getPushdownLabelFiltersForLabelSet(args []Expr, lfs []LabelFilter) []LabelFilter {
|
||||
m := make(map[string]struct{})
|
||||
for i := 0; i < len(args); i += 2 {
|
||||
labelName := args[i]
|
||||
seLabelName, ok := labelName.(*StringExpr)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
m[seLabelName.S] = struct{}{}
|
||||
func pushdownLabelFiltersForLabelKeep(args []Expr, lfs []LabelFilter) {
|
||||
if len(args) == 0 {
|
||||
return
|
||||
}
|
||||
lfs = keepLabelFiltersForLabelNames(lfs, args[1:])
|
||||
pushdownBinaryOpFiltersInplace(args[0], lfs)
|
||||
}
|
||||
|
||||
var lfsDst []LabelFilter
|
||||
for _, lf := range lfs {
|
||||
if _, ok := m[lf.Label]; !ok {
|
||||
lfsDst = append(lfsDst, lf)
|
||||
}
|
||||
func pushdownLabelFiltersForLabelDel(args []Expr, lfs []LabelFilter) {
|
||||
if len(args) == 0 {
|
||||
return
|
||||
}
|
||||
return lfsDst
|
||||
lfs = dropLabelFiltersForLabelNames(lfs, args[1:])
|
||||
pushdownBinaryOpFiltersInplace(args[0], lfs)
|
||||
}
|
||||
|
||||
func pushdownLabelFiltersForLabelCopy(args []Expr, lfs []LabelFilter) {
|
||||
if len(args) == 0 {
|
||||
return
|
||||
}
|
||||
arg := args[0]
|
||||
args = args[1:]
|
||||
var labelNames []Expr
|
||||
for i := 0; i < len(args); i += 2 {
|
||||
if i+1 >= len(args) {
|
||||
return
|
||||
}
|
||||
labelNames = append(labelNames, args[i+1])
|
||||
}
|
||||
lfs = dropLabelFiltersForLabelNames(lfs, labelNames)
|
||||
pushdownBinaryOpFiltersInplace(arg, lfs)
|
||||
}
|
||||
|
||||
func pushdownLabelFiltersForLabelReplace(args []Expr, lfs []LabelFilter) {
|
||||
if len(args) < 2 {
|
||||
return
|
||||
}
|
||||
lfs = dropLabelFiltersForLabelName(lfs, args[1])
|
||||
pushdownBinaryOpFiltersInplace(args[0], lfs)
|
||||
}
|
||||
|
||||
func pushdownLabelFiltersForLabelSet(args []Expr, lfs []LabelFilter) {
|
||||
if len(args) == 0 {
|
||||
return
|
||||
}
|
||||
arg := args[0]
|
||||
args = args[1:]
|
||||
var labelNames []Expr
|
||||
for i := 0; i < len(args); i += 2 {
|
||||
labelNames = append(labelNames, args[i])
|
||||
}
|
||||
lfs = dropLabelFiltersForLabelNames(lfs, labelNames)
|
||||
pushdownBinaryOpFiltersInplace(arg, lfs)
|
||||
}
|
||||
|
||||
func intersectLabelFilters(lfsA, lfsB []LabelFilter) []LabelFilter {
|
||||
|
@ -354,6 +444,48 @@ func intersectLabelFilters(lfsA, lfsB []LabelFilter) []LabelFilter {
|
|||
return lfs
|
||||
}
|
||||
|
||||
func keepLabelFiltersForLabelNames(lfs []LabelFilter, labelNames []Expr) []LabelFilter {
|
||||
m := make(map[string]struct{}, len(labelNames))
|
||||
for _, labelName := range labelNames {
|
||||
seLabelName, ok := labelName.(*StringExpr)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
m[seLabelName.S] = struct{}{}
|
||||
}
|
||||
|
||||
var lfsDst []LabelFilter
|
||||
for _, lf := range lfs {
|
||||
if _, ok := m[lf.Label]; ok {
|
||||
lfsDst = append(lfsDst, lf)
|
||||
}
|
||||
}
|
||||
|
||||
return lfsDst
|
||||
}
|
||||
|
||||
func dropLabelFiltersForLabelNames(lfs []LabelFilter, labelNames []Expr) []LabelFilter {
|
||||
for _, labelName := range labelNames {
|
||||
lfs = dropLabelFiltersForLabelName(lfs, labelName)
|
||||
}
|
||||
return lfs
|
||||
}
|
||||
|
||||
func dropLabelFiltersForLabelName(lfs []LabelFilter, labelName Expr) []LabelFilter {
|
||||
seLabelName, ok := labelName.(*StringExpr)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
lfsDst := make([]LabelFilter, 0, len(lfs))
|
||||
for _, lf := range lfs {
|
||||
if lf.Label != seLabelName.S {
|
||||
lfsDst = append(lfsDst, lf)
|
||||
}
|
||||
}
|
||||
return lfsDst
|
||||
}
|
||||
|
||||
func unionLabelFilters(lfsA, lfsB []LabelFilter) []LabelFilter {
|
||||
if len(lfsA) == 0 {
|
||||
return lfsB
|
||||
|
@ -498,7 +630,13 @@ func getRollupArgIdxForOptimization(funcName string, args []Expr) int {
|
|||
|
||||
func getTransformArgIdxForOptimization(funcName string, args []Expr) int {
|
||||
switch strings.ToLower(funcName) {
|
||||
case "", "absent", "scalar", "union", "vector", "range_normalize":
|
||||
case "label_copy", "label_del", "label_join", "label_keep", "label_lowercase", "label_map",
|
||||
"label_match", "label_mismatch", "label_move", "label_replace", "label_set", "label_transform",
|
||||
"label_uppercase", "labels_equal":
|
||||
panic(fmt.Errorf("BUG: unexpected funcName passed to getTransformArgIdxForOptimization: %s", funcName))
|
||||
case "drop_common_labels", "range_normalize":
|
||||
return -1
|
||||
case "", "absent", "scalar", "union", "vector":
|
||||
return -1
|
||||
case "end", "now", "pi", "ru", "start", "step", "time":
|
||||
return -1
|
||||
|
@ -509,9 +647,8 @@ func getTransformArgIdxForOptimization(funcName string, args []Expr) int {
|
|||
return 1
|
||||
case "histogram_quantiles":
|
||||
return len(args) - 1
|
||||
case "drop_common_labels", "label_copy", "label_del", "label_graphite_group", "label_join", "label_keep", "label_lowercase",
|
||||
"label_map", "label_move", "label_replace", "label_set", "label_transform", "label_uppercase":
|
||||
return -1
|
||||
case "label_graphite_group":
|
||||
return 0
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
|
|
222
vendor/github.com/VictoriaMetrics/metricsql/parser.go
generated
vendored
222
vendor/github.com/VictoriaMetrics/metricsql/parser.go
generated
vendored
|
@ -13,6 +13,26 @@ import (
|
|||
//
|
||||
// MetricsQL is backwards-compatible with PromQL.
|
||||
func Parse(s string) (Expr, error) {
|
||||
// Parse s
|
||||
e, err := parseInternal(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Expand `WITH` expressions.
|
||||
was := getDefaultWithArgExprs()
|
||||
if e, err = expandWithExpr(was, e); err != nil {
|
||||
return nil, fmt.Errorf(`cannot expand WITH expressions: %s`, err)
|
||||
}
|
||||
e = removeParensExpr(e)
|
||||
e = simplifyConstants(e)
|
||||
if err := checkSupportedFunctions(e); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func parseInternal(s string) (Expr, error) {
|
||||
var p parser
|
||||
p.lex.Init(s)
|
||||
if err := p.lex.Next(); err != nil {
|
||||
|
@ -25,15 +45,6 @@ func Parse(s string) (Expr, error) {
|
|||
if !isEOF(p.lex.Token) {
|
||||
return nil, fmt.Errorf(`unparsed data left: %q`, p.lex.Context())
|
||||
}
|
||||
was := getDefaultWithArgExprs()
|
||||
if e, err = expandWithExpr(was, e); err != nil {
|
||||
return nil, fmt.Errorf(`cannot expand WITH expressions: %s`, err)
|
||||
}
|
||||
e = removeParensExpr(e)
|
||||
e = simplifyConstants(e)
|
||||
if err := checkSupportedFunctions(e); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
|
@ -104,36 +115,33 @@ func mustParseWithArgExpr(s string) *withArgExpr {
|
|||
|
||||
// removeParensExpr removes parensExpr for (Expr) case.
|
||||
func removeParensExpr(e Expr) Expr {
|
||||
if re, ok := e.(*RollupExpr); ok {
|
||||
re.Expr = removeParensExpr(re.Expr)
|
||||
if re.At != nil {
|
||||
re.At = removeParensExpr(re.At)
|
||||
switch t := e.(type) {
|
||||
case *RollupExpr:
|
||||
t.Expr = removeParensExpr(t.Expr)
|
||||
if t.At != nil {
|
||||
t.At = removeParensExpr(t.At)
|
||||
}
|
||||
return re
|
||||
}
|
||||
if be, ok := e.(*BinaryOpExpr); ok {
|
||||
be.Left = removeParensExpr(be.Left)
|
||||
be.Right = removeParensExpr(be.Right)
|
||||
return be
|
||||
}
|
||||
if ae, ok := e.(*AggrFuncExpr); ok {
|
||||
for i, arg := range ae.Args {
|
||||
ae.Args[i] = removeParensExpr(arg)
|
||||
return t
|
||||
case *BinaryOpExpr:
|
||||
t.Left = removeParensExpr(t.Left)
|
||||
t.Right = removeParensExpr(t.Right)
|
||||
return t
|
||||
case *AggrFuncExpr:
|
||||
for i, arg := range t.Args {
|
||||
t.Args[i] = removeParensExpr(arg)
|
||||
}
|
||||
return ae
|
||||
}
|
||||
if fe, ok := e.(*FuncExpr); ok {
|
||||
for i, arg := range fe.Args {
|
||||
fe.Args[i] = removeParensExpr(arg)
|
||||
return t
|
||||
case *FuncExpr:
|
||||
for i, arg := range t.Args {
|
||||
t.Args[i] = removeParensExpr(arg)
|
||||
}
|
||||
return fe
|
||||
}
|
||||
if pe, ok := e.(*parensExpr); ok {
|
||||
args := *pe
|
||||
return t
|
||||
case *parensExpr:
|
||||
args := *t
|
||||
for i, arg := range args {
|
||||
args[i] = removeParensExpr(arg)
|
||||
}
|
||||
if len(*pe) == 1 {
|
||||
if len(*t) == 1 {
|
||||
return args[0]
|
||||
}
|
||||
// Treat parensExpr as a function with empty name, i.e. union()
|
||||
|
@ -142,38 +150,43 @@ func removeParensExpr(e Expr) Expr {
|
|||
Args: args,
|
||||
}
|
||||
return fe
|
||||
case *withExpr:
|
||||
for _, arg := range t.Was {
|
||||
arg.Expr = removeParensExpr(arg.Expr)
|
||||
}
|
||||
t.Expr = removeParensExpr(t.Expr)
|
||||
return t
|
||||
default:
|
||||
return e
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func simplifyConstants(e Expr) Expr {
|
||||
if re, ok := e.(*RollupExpr); ok {
|
||||
re.Expr = simplifyConstants(re.Expr)
|
||||
if re.At != nil {
|
||||
re.At = simplifyConstants(re.At)
|
||||
switch t := e.(type) {
|
||||
case *withExpr:
|
||||
panic(fmt.Errorf("BUG: withExpr shouldn't be passed to simplifyConstants"))
|
||||
case *parensExpr:
|
||||
panic(fmt.Errorf("BUG: parensExpr shouldn't be passed to simplifyConstants"))
|
||||
case *RollupExpr:
|
||||
t.Expr = simplifyConstants(t.Expr)
|
||||
if t.At != nil {
|
||||
t.At = simplifyConstants(t.At)
|
||||
}
|
||||
return re
|
||||
}
|
||||
if ae, ok := e.(*AggrFuncExpr); ok {
|
||||
simplifyConstantsInplace(ae.Args)
|
||||
return ae
|
||||
}
|
||||
if fe, ok := e.(*FuncExpr); ok {
|
||||
simplifyConstantsInplace(fe.Args)
|
||||
return fe
|
||||
}
|
||||
if pe, ok := e.(*parensExpr); ok {
|
||||
if len(*pe) == 1 {
|
||||
return simplifyConstants((*pe)[0])
|
||||
}
|
||||
simplifyConstantsInplace(*pe)
|
||||
return pe
|
||||
}
|
||||
be, ok := e.(*BinaryOpExpr)
|
||||
if !ok {
|
||||
return t
|
||||
case *AggrFuncExpr:
|
||||
simplifyConstantsInplace(t.Args)
|
||||
return t
|
||||
case *FuncExpr:
|
||||
simplifyConstantsInplace(t.Args)
|
||||
return t
|
||||
case *BinaryOpExpr:
|
||||
return simplifyConstantsInBinaryExpr(t)
|
||||
default:
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
func simplifyConstantsInBinaryExpr(be *BinaryOpExpr) Expr {
|
||||
be.Left = simplifyConstants(be.Left)
|
||||
be.Right = simplifyConstants(be.Right)
|
||||
|
||||
|
@ -202,7 +215,7 @@ func simplifyConstants(e Expr) Expr {
|
|||
return be
|
||||
}
|
||||
// Perform string comparisons.
|
||||
ok = false
|
||||
ok := false
|
||||
switch be.Op {
|
||||
case "==":
|
||||
ok = lse.S == rse.S
|
||||
|
@ -1715,7 +1728,13 @@ type StringExpr struct {
|
|||
// AppendString appends string representation of se to dst and returns the result.
|
||||
func (se *StringExpr) AppendString(dst []byte) []byte {
|
||||
if len(se.tokens) > 0 {
|
||||
panic(fmt.Errorf("BUG: StringExpr=%q must be already parsed with expandWithExpr()", se.tokens))
|
||||
for i, token := range se.tokens {
|
||||
dst = append(dst, token...)
|
||||
if i+1 < len(se.tokens) {
|
||||
dst = append(dst, '+')
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
return strconv.AppendQuote(dst, se.S)
|
||||
}
|
||||
|
@ -2182,15 +2201,24 @@ type MetricExpr struct {
|
|||
}
|
||||
|
||||
func appendLabelFilterss(dst []byte, lfss [][]*labelFilterExpr) []byte {
|
||||
offset := 0
|
||||
metricName := getMetricNameFromLabelFilterss(lfss)
|
||||
if metricName != "" {
|
||||
offset = 1
|
||||
dst = appendEscapedIdent(dst, metricName)
|
||||
}
|
||||
if isOnlyMetricNameInLabelFilterss(lfss) {
|
||||
return dst
|
||||
}
|
||||
|
||||
dst = append(dst, '{')
|
||||
for i, lfs := range lfss {
|
||||
for j, lf := range lfs {
|
||||
dst = lf.AppendString(dst)
|
||||
if j+1 < len(lfs) {
|
||||
dst = append(dst, ',')
|
||||
}
|
||||
lfs = lfs[offset:]
|
||||
if len(lfs) == 0 {
|
||||
continue
|
||||
}
|
||||
if i+1 < len(lfss) {
|
||||
dst = appendLabelFilterExprs(dst, lfs)
|
||||
if i+1 < len(lfss) && len(lfss[i+1]) > offset {
|
||||
dst = append(dst, " or "...)
|
||||
}
|
||||
}
|
||||
|
@ -2198,11 +2226,59 @@ func appendLabelFilterss(dst []byte, lfss [][]*labelFilterExpr) []byte {
|
|||
return dst
|
||||
}
|
||||
|
||||
func appendLabelFilterExprs(dst []byte, lfs []*labelFilterExpr) []byte {
|
||||
for i, lf := range lfs {
|
||||
dst = lf.AppendString(dst)
|
||||
if i+1 < len(lfs) {
|
||||
dst = append(dst, ',')
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
func isOnlyMetricNameInLabelFilterss(lfss [][]*labelFilterExpr) bool {
|
||||
if getMetricNameFromLabelFilterss(lfss) == "" {
|
||||
return false
|
||||
}
|
||||
for _, lfs := range lfss {
|
||||
if len(lfs) > 1 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func getMetricNameFromLabelFilterss(lfss [][]*labelFilterExpr) string {
|
||||
if len(lfss) == 0 || len(lfss[0]) == 0 || lfss[0][0].Label != "__name__" || len(lfss[0][0].Value.tokens) != 1 {
|
||||
return ""
|
||||
}
|
||||
metricName := mustExtractMetricNameFromToken(lfss[0][0].Value.tokens[0])
|
||||
for _, lfs := range lfss[1:] {
|
||||
if len(lfs) == 0 || lfs[0].Label != "__name__" || len(lfs[0].Value.tokens) != 1 {
|
||||
return ""
|
||||
}
|
||||
metricNameLocal := mustExtractMetricNameFromToken(lfs[0].Value.tokens[0])
|
||||
if metricNameLocal != metricName {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return metricName
|
||||
}
|
||||
|
||||
func mustExtractMetricNameFromToken(token string) string {
|
||||
metricName, err := extractStringValue(token)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("BUG: cannot obtain metric name: %w", err))
|
||||
}
|
||||
return metricName
|
||||
}
|
||||
|
||||
// AppendString appends string representation of me to dst and returns the result.
|
||||
func (me *MetricExpr) AppendString(dst []byte) []byte {
|
||||
if len(me.labelFilterss) > 0 {
|
||||
return appendLabelFilterss(dst, me.labelFilterss)
|
||||
}
|
||||
|
||||
lfss := me.LabelFilterss
|
||||
if len(lfss) == 0 {
|
||||
dst = append(dst, "{}"...)
|
||||
|
@ -2214,15 +2290,19 @@ func (me *MetricExpr) AppendString(dst []byte) []byte {
|
|||
offset = 1
|
||||
dst = appendEscapedIdent(dst, metricName)
|
||||
}
|
||||
if len(lfss) == 1 && len(lfss[0]) == offset {
|
||||
if me.isOnlyMetricName() {
|
||||
return dst
|
||||
}
|
||||
dst = append(dst, '{')
|
||||
lfs := lfss[0]
|
||||
dst = appendLabelFilters(dst, lfs[offset:])
|
||||
for _, lfs := range lfss[1:] {
|
||||
dst = append(dst, " or "...)
|
||||
dst = appendLabelFilters(dst, lfs[offset:])
|
||||
for i, lfs := range lfss {
|
||||
lfs = lfs[offset:]
|
||||
if len(lfs) == 0 {
|
||||
continue
|
||||
}
|
||||
dst = appendLabelFilters(dst, lfs)
|
||||
if i+1 < len(lfss) && len(lfss[i+1]) > offset {
|
||||
dst = append(dst, " or "...)
|
||||
}
|
||||
}
|
||||
dst = append(dst, '}')
|
||||
return dst
|
||||
|
|
56
vendor/github.com/VictoriaMetrics/metricsql/prettifier.go
generated
vendored
56
vendor/github.com/VictoriaMetrics/metricsql/prettifier.go
generated
vendored
|
@ -2,10 +2,11 @@ package metricsql
|
|||
|
||||
// Prettify returns prettified representation of MetricsQL query q.
|
||||
func Prettify(q string) (string, error) {
|
||||
e, err := Parse(q)
|
||||
e, err := parseInternal(q)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
e = removeParensExpr(e)
|
||||
b := appendPrettifiedExpr(nil, e, 0, false)
|
||||
return string(b), nil
|
||||
}
|
||||
|
@ -28,11 +29,11 @@ func appendPrettifiedExpr(dst []byte, e Expr, indent int, needParens bool) []byt
|
|||
dst = append(dst, ')')
|
||||
}
|
||||
if len(dst)-dstLen <= maxPrettifiedLineLen {
|
||||
// There is no need in splitting the e string representation, since its' length doesn't exceed.
|
||||
// There is no need in splitting the e string representation, since its' length doesn't exceed maxPrettifiedLineLen.
|
||||
return dst
|
||||
}
|
||||
|
||||
// The e string representation exceeds maxPrettifiedLineLen. Split it into multiple lines
|
||||
// The e string representation exceeds maxPrettifiedLineLen. Split it into multiple lines.
|
||||
dst = dst[:dstLen]
|
||||
if needParens {
|
||||
dst = appendIndent(dst, indent)
|
||||
|
@ -40,6 +41,37 @@ func appendPrettifiedExpr(dst []byte, e Expr, indent int, needParens bool) []byt
|
|||
indent++
|
||||
}
|
||||
switch t := e.(type) {
|
||||
case *withExpr:
|
||||
// Put every WITH expression on a separate line
|
||||
dst = appendIndent(dst, indent)
|
||||
dst = append(dst, "WITH (\n"...)
|
||||
indent++
|
||||
for _, wa := range t.Was {
|
||||
dst = appendPrettifiedExpr(dst, wa, indent, false)
|
||||
dst = append(dst, ",\n"...)
|
||||
}
|
||||
indent--
|
||||
dst = appendIndent(dst, indent)
|
||||
dst = append(dst, ")\n"...)
|
||||
dst = appendPrettifiedExpr(dst, t.Expr, indent, false)
|
||||
case *withArgExpr:
|
||||
// Wrap long withArgExpr into `(...)`
|
||||
dst = appendIndent(dst, indent)
|
||||
dst = appendEscapedIdent(dst, t.Name)
|
||||
if len(t.Args) > 0 {
|
||||
dst = append(dst, '(')
|
||||
dst = appendEscapedIdent(dst, t.Args[0])
|
||||
for _, arg := range t.Args[1:] {
|
||||
dst = append(dst, ", "...)
|
||||
dst = appendEscapedIdent(dst, arg)
|
||||
}
|
||||
dst = append(dst, ')')
|
||||
}
|
||||
dst = append(dst, " = (\n"...)
|
||||
dst = appendPrettifiedExpr(dst, t.Expr, indent+1, false)
|
||||
dst = append(dst, '\n')
|
||||
dst = appendIndent(dst, indent)
|
||||
dst = append(dst, ')')
|
||||
case *BinaryOpExpr:
|
||||
// Split:
|
||||
//
|
||||
|
@ -125,20 +157,24 @@ func appendPrettifiedExpr(dst []byte, e Expr, indent int, needParens bool) []byt
|
|||
// or
|
||||
// filtersN
|
||||
// }
|
||||
lfss := t.labelFilterss
|
||||
offset := 0
|
||||
metricName := t.getMetricName()
|
||||
metricName := getMetricNameFromLabelFilterss(lfss)
|
||||
if metricName != "" {
|
||||
offset = 1
|
||||
}
|
||||
dst = appendIndent(dst, indent)
|
||||
dst = appendEscapedIdent(dst, metricName)
|
||||
if !t.isOnlyMetricName() {
|
||||
if !isOnlyMetricNameInLabelFilterss(lfss) {
|
||||
dst = append(dst, "{\n"...)
|
||||
lfss := t.LabelFilterss
|
||||
for i, lfs := range lfss {
|
||||
dst = appendPrettifiedLabelFilters(dst, indent+1, lfs[offset:])
|
||||
lfs = lfs[offset:]
|
||||
if len(lfs) == 0 {
|
||||
continue
|
||||
}
|
||||
dst = appendPrettifiedLabelFilters(dst, indent+1, lfs)
|
||||
dst = append(dst, '\n')
|
||||
if i+1 < len(lfss) {
|
||||
if i+1 < len(lfss) && len(lfss[i+1]) > offset {
|
||||
dst = appendIndent(dst, indent+2)
|
||||
dst = append(dst, "or\n"...)
|
||||
}
|
||||
|
@ -173,12 +209,12 @@ func appendPrettifiedFuncArgs(dst []byte, indent int, args []Expr) []byte {
|
|||
return dst
|
||||
}
|
||||
|
||||
func appendPrettifiedLabelFilters(dst []byte, indent int, lfs []LabelFilter) []byte {
|
||||
func appendPrettifiedLabelFilters(dst []byte, indent int, lfs []*labelFilterExpr) []byte {
|
||||
dstLen := len(dst)
|
||||
|
||||
// Try marshaling lfs into a single line
|
||||
dst = appendIndent(dst, indent)
|
||||
dst = appendLabelFilters(dst, lfs)
|
||||
dst = appendLabelFilterExprs(dst, lfs)
|
||||
if len(dst)-dstLen <= maxPrettifiedLineLen {
|
||||
return dst
|
||||
}
|
||||
|
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
|
@ -102,7 +102,7 @@ github.com/VictoriaMetrics/fastcache
|
|||
# github.com/VictoriaMetrics/metrics v1.32.0
|
||||
## explicit; go 1.17
|
||||
github.com/VictoriaMetrics/metrics
|
||||
# github.com/VictoriaMetrics/metricsql v0.72.1
|
||||
# github.com/VictoriaMetrics/metricsql v0.73.0
|
||||
## explicit; go 1.13
|
||||
github.com/VictoriaMetrics/metricsql
|
||||
github.com/VictoriaMetrics/metricsql/binaryop
|
||||
|
|
Loading…
Reference in a new issue