diff --git a/go.mod b/go.mod index bc6317eb8..d9f96a639 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( // like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b github.com/VictoriaMetrics/fasthttp v1.2.0 github.com/VictoriaMetrics/metrics v1.24.0 - github.com/VictoriaMetrics/metricsql v0.59.1 + github.com/VictoriaMetrics/metricsql v0.60.0 github.com/aws/aws-sdk-go-v2 v1.19.0 github.com/aws/aws-sdk-go-v2/config v1.18.28 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.72 diff --git a/go.sum b/go.sum index 78b7b8dae..a2b4f2080 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ github.com/VictoriaMetrics/fasthttp v1.2.0 h1:nd9Wng4DlNtaI27WlYh5mGXCJOmee/2c2b github.com/VictoriaMetrics/fasthttp v1.2.0/go.mod h1:zv5YSmasAoSyv8sBVexfArzFDIGGTN4TfCKAtAw7IfE= github.com/VictoriaMetrics/metrics v1.24.0 h1:ILavebReOjYctAGY5QU2F9X0MYvkcrG3aEn2RKa1Zkw= github.com/VictoriaMetrics/metrics v1.24.0/go.mod h1:eFT25kvsTidQFHb6U0oa0rTrDRdz4xTYjpL8+UPohys= -github.com/VictoriaMetrics/metricsql v0.59.1 h1:G7FJLyYQlM9kSIK9EWDW8Dc7J0Bke3Onfle3Syr3CBs= -github.com/VictoriaMetrics/metricsql v0.59.1/go.mod h1:k4UaP/+CjuZslIjd+kCigNG9TQmUqh5v0TP/nMEy90I= +github.com/VictoriaMetrics/metricsql v0.60.0 h1:KlVWTabXGu/50U3Dp72TyJYo01WTaxSsHwMLiE9yHuA= +github.com/VictoriaMetrics/metricsql v0.60.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= diff --git a/vendor/github.com/VictoriaMetrics/metricsql/parser.go b/vendor/github.com/VictoriaMetrics/metricsql/parser.go index 209ed08fd..55339f06c 100644 --- a/vendor/github.com/VictoriaMetrics/metricsql/parser.go +++ b/vendor/github.com/VictoriaMetrics/metricsql/parser.go @@ -1696,22 +1696,7 @@ func (be *BinaryOpExpr) appendStringNoKeepMetricNames(dst []byte) []byte { dst = be.Left.AppendString(dst) } dst = append(dst, ' ') - dst = append(dst, be.Op...) - if be.Bool { - dst = append(dst, "bool"...) - } - if be.GroupModifier.Op != "" { - dst = append(dst, ' ') - dst = be.GroupModifier.AppendString(dst) - } - if be.JoinModifier.Op != "" { - dst = append(dst, ' ') - dst = be.JoinModifier.AppendString(dst) - if prefix := be.JoinModifierPrefix; prefix != nil { - dst = append(dst, " prefix "...) - dst = prefix.AppendString(dst) - } - } + dst = be.appendModifiers(dst) dst = append(dst, ' ') if be.needRightParens() { dst = appendArgInParens(dst, be.Right) @@ -1737,12 +1722,32 @@ func (be *BinaryOpExpr) needRightParens() bool { if isReservedBinaryOpIdent(t.Name) { return true } - return be.KeepMetricNames + return t.KeepMetricNames || be.KeepMetricNames default: return false } } +func (be *BinaryOpExpr) appendModifiers(dst []byte) []byte { + dst = append(dst, be.Op...) + if be.Bool { + dst = append(dst, "bool"...) + } + if be.GroupModifier.Op != "" { + dst = append(dst, ' ') + dst = be.GroupModifier.AppendString(dst) + } + if be.JoinModifier.Op != "" { + dst = append(dst, ' ') + dst = be.JoinModifier.AppendString(dst) + if prefix := be.JoinModifierPrefix; prefix != nil { + dst = append(dst, " prefix "...) + dst = prefix.AppendString(dst) + } + } + return dst +} + func needBinaryOpArgParens(arg Expr) bool { switch t := arg.(type) { case *BinaryOpExpr: @@ -1827,6 +1832,10 @@ type FuncExpr struct { func (fe *FuncExpr) AppendString(dst []byte) []byte { dst = appendEscapedIdent(dst, fe.Name) dst = appendStringArgListExpr(dst, fe.Args) + return fe.appendModifiers(dst) +} + +func (fe *FuncExpr) appendModifiers(dst []byte) []byte { if fe.KeepMetricNames { dst = append(dst, " keep_metric_names"...) } @@ -1855,6 +1864,10 @@ type AggrFuncExpr struct { func (ae *AggrFuncExpr) AppendString(dst []byte) []byte { dst = appendEscapedIdent(dst, ae.Name) dst = appendStringArgListExpr(dst, ae.Args) + return ae.appendModifiers(dst) +} + +func (ae *AggrFuncExpr) appendModifiers(dst []byte) []byte { if ae.Modifier.Op != "" { dst = append(dst, ' ') dst = ae.Modifier.AppendString(dst) @@ -1954,18 +1967,7 @@ func (re *RollupExpr) ForSubquery() bool { // AppendString appends string representation of re to dst and returns the result. func (re *RollupExpr) AppendString(dst []byte) []byte { - needParens := func() bool { - if _, ok := re.Expr.(*RollupExpr); ok { - return true - } - if _, ok := re.Expr.(*BinaryOpExpr); ok { - return true - } - if ae, ok := re.Expr.(*AggrFuncExpr); ok && ae.Modifier.Op != "" { - return true - } - return false - }() + needParens := re.needParens() if needParens { dst = append(dst, '(') } @@ -1973,6 +1975,10 @@ func (re *RollupExpr) AppendString(dst []byte) []byte { if needParens { dst = append(dst, ')') } + return re.appendModifiers(dst) +} + +func (re *RollupExpr) appendModifiers(dst []byte) []byte { if re.Window != nil || re.InheritStep || re.Step != nil { dst = append(dst, '[') dst = re.Window.AppendString(dst) @@ -2002,6 +2008,17 @@ func (re *RollupExpr) AppendString(dst []byte) []byte { return dst } +func (re *RollupExpr) needParens() bool { + switch t := re.Expr.(type) { + case *RollupExpr, *BinaryOpExpr: + return true + case *AggrFuncExpr: + return t.Modifier.Op != "" + default: + return false + } +} + // LabelFilter represents MetricsQL label filter like `foo="bar"`. type LabelFilter struct { // Label contains label name for the filter. diff --git a/vendor/github.com/VictoriaMetrics/metricsql/prettifier.go b/vendor/github.com/VictoriaMetrics/metricsql/prettifier.go new file mode 100644 index 000000000..486a22492 --- /dev/null +++ b/vendor/github.com/VictoriaMetrics/metricsql/prettifier.go @@ -0,0 +1,201 @@ +package metricsql + +// Prettify returns prettified representation of MetricsQL query q. +func Prettify(q string) (string, error) { + e, err := Parse(q) + if err != nil { + return "", err + } + b := appendPrettifiedExpr(nil, e, 0, false) + return string(b), nil +} + +// maxPrettifiedLineLen is the maximum length of a single line returned by Prettify(). +// +// Actual lines may exceed the maximum length in some cases. +const maxPrettifiedLineLen = 80 + +func appendPrettifiedExpr(dst []byte, e Expr, indent int, needParens bool) []byte { + dstLen := len(dst) + + // Try appending e to dst and check whether its length exceeds the maximum allowed line length. + dst = appendIndent(dst, indent) + if needParens { + dst = append(dst, '(') + } + dst = e.AppendString(dst) + if needParens { + dst = append(dst, ')') + } + if len(dst)-dstLen <= maxPrettifiedLineLen { + // There is no need in splitting the e string representation, since its' length doesn't exceed. + return dst + } + + // The e string representation exceeds maxPrettifiedLineLen. Split it into multiple lines + dst = dst[:dstLen] + if needParens { + dst = appendIndent(dst, indent) + dst = append(dst, "(\n"...) + indent++ + } + switch t := e.(type) { + case *BinaryOpExpr: + // Split: + // + // a op b + // + // into: + // + // foo + // op + // bar + if t.KeepMetricNames { + dst = appendIndent(dst, indent) + dst = append(dst, "(\n"...) + indent++ + } + dst = appendPrettifiedExpr(dst, t.Left, indent, t.needLeftParens()) + dst = append(dst, '\n') + dst = appendIndent(dst, indent+1) + dst = t.appendModifiers(dst) + dst = append(dst, '\n') + dst = appendPrettifiedExpr(dst, t.Right, indent, t.needRightParens()) + if t.KeepMetricNames { + indent-- + dst = append(dst, '\n') + dst = appendIndent(dst, indent) + dst = append(dst, ") keep_metric_names"...) + } + case *RollupExpr: + // Split: + // + // q[d:s] offset off @ x + // + // into: + // + // ( + // q + // )[d:s] offset off @ x + dst = appendPrettifiedExpr(dst, t.Expr, indent, t.needParens()) + dst = t.appendModifiers(dst) + case *AggrFuncExpr: + // Split: + // + // aggr_func(arg1, ..., argN) modifiers + // + // into: + // + // aggr_func( + // arg1, + // ... + // argN + // ) modifiers + dst = appendIndent(dst, indent) + dst = appendEscapedIdent(dst, t.Name) + dst = appendPrettifiedFuncArgs(dst, indent, t.Args) + dst = t.appendModifiers(dst) + case *FuncExpr: + // Split: + // + // func(arg1, ..., argN) modifiers + // + // into: + // + // func( + // arg1, + // ... + // argN + // ) modifiers + dst = appendIndent(dst, indent) + dst = appendEscapedIdent(dst, t.Name) + dst = appendPrettifiedFuncArgs(dst, indent, t.Args) + dst = t.appendModifiers(dst) + case *MetricExpr: + // Split: + // + // metric{filters1 or ... or filtersN} + // + // into: + // + // metric{ + // filters1 + // or + // ... + // or + // filtersN + // } + offset := 0 + metricName := t.getMetricName() + if metricName != "" { + offset = 1 + } + dst = appendIndent(dst, indent) + dst = appendEscapedIdent(dst, metricName) + dst = append(dst, "{\n"...) + lfss := t.LabelFilterss + for i, lfs := range lfss { + dst = appendPrettifiedLabelFilters(dst, indent+1, lfs[offset:]) + dst = append(dst, '\n') + if i+1 < len(lfss) { + dst = appendIndent(dst, indent+2) + dst = append(dst, "or\n"...) + } + } + dst = appendIndent(dst, indent) + dst = append(dst, '}') + default: + // marshal other expressions as is + dst = t.AppendString(dst) + } + if needParens { + indent-- + dst = append(dst, '\n') + dst = appendIndent(dst, indent) + dst = append(dst, ')') + } + return dst +} + +func appendPrettifiedFuncArgs(dst []byte, indent int, args []Expr) []byte { + dst = append(dst, "(\n"...) + for i, arg := range args { + dst = appendPrettifiedExpr(dst, arg, indent+1, false) + if i+1 < len(args) { + dst = append(dst, ',') + } + dst = append(dst, '\n') + } + dst = appendIndent(dst, indent) + dst = append(dst, ')') + return dst +} + +func appendPrettifiedLabelFilters(dst []byte, indent int, lfs []LabelFilter) []byte { + dstLen := len(dst) + + // Try marshaling lfs into a single line + dst = appendIndent(dst, indent) + dst = appendLabelFilters(dst, lfs) + if len(dst)-dstLen <= maxPrettifiedLineLen { + return dst + } + + // Too long line - split it into multiple lines + dst = dst[:dstLen] + for i := range lfs { + dst = appendIndent(dst, indent) + dst = lfs[i].AppendString(dst) + if i+1 < len(lfs) { + dst = append(dst, ",\n"...) + } + } + return dst +} + +func appendIndent(dst []byte, indent int) []byte { + for i := 0; i < indent; i++ { + dst = append(dst, " "...) + } + return dst +} diff --git a/vendor/modules.txt b/vendor/modules.txt index a79da8883..82c8a37ba 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -99,7 +99,7 @@ github.com/VictoriaMetrics/fasthttp/stackless # github.com/VictoriaMetrics/metrics v1.24.0 ## explicit; go 1.20 github.com/VictoriaMetrics/metrics -# github.com/VictoriaMetrics/metricsql v0.59.1 +# github.com/VictoriaMetrics/metricsql v0.60.0 ## explicit; go 1.13 github.com/VictoriaMetrics/metricsql github.com/VictoriaMetrics/metricsql/binaryop