Merge pull request #795 from prometheus/fabxc/promql-print

Fix print bug, remove DotGraph methods
This commit is contained in:
Julius Volz 2015-06-12 14:05:05 +02:00
commit 0542733964
3 changed files with 53 additions and 159 deletions

View File

@ -40,8 +40,6 @@ type Node interface {
// String representation of the node that returns the given node when parsed
// as part of a valid query.
String() string
// DotGraph returns a dot graph representation of the node.
DotGraph() string
}
// Statement is a generic interface for all statements.

View File

@ -15,7 +15,6 @@ package promql
import (
"fmt"
"reflect"
"sort"
"strings"
@ -178,7 +177,11 @@ func (es Expressions) String() (s string) {
func (node *AggregateExpr) String() string {
aggrString := fmt.Sprintf("%s(%s)", node.Op, node.Expr)
if len(node.Grouping) > 0 {
return fmt.Sprintf("%s BY (%s)", aggrString, node.Grouping)
format := "%s BY (%s)"
if node.KeepExtraLabels {
format += " KEEPING_EXTRA"
}
return fmt.Sprintf(format, aggrString, node.Grouping)
}
return aggrString
}
@ -242,158 +245,3 @@ func (node *VectorSelector) String() string {
sort.Strings(labelStrings)
return fmt.Sprintf("%s{%s}", node.Name, strings.Join(labelStrings, ","))
}
// DotGraph returns a DOT representation of a statement list.
func (ss Statements) DotGraph() string {
graph := ""
for _, stmt := range ss {
graph += stmt.DotGraph()
}
return graph
}
// DotGraph returns a DOT representation of the alert statement.
func (node *AlertStmt) DotGraph() string {
graph := fmt.Sprintf(
`digraph "Alert Statement" {
%#p[shape="box",label="ALERT %s IF FOR %s"];
%#p -> %x;
%s
}`,
node, node.Name, strutil.DurationToString(node.Duration),
node, reflect.ValueOf(node.Expr).Pointer(),
node.Expr.DotGraph(),
)
return graph
}
// DotGraph returns a DOT representation of the eval statement.
func (node *EvalStmt) DotGraph() string {
graph := fmt.Sprintf(
`%#p[shape="box",label="[%d:%s:%d]";
%#p -> %x;
%s
}`,
node, node.Start, node.End, node.Interval,
node, reflect.ValueOf(node.Expr).Pointer(),
node.Expr.DotGraph(),
)
return graph
}
// DotGraph returns a DOT representation of the record statement.
func (node *RecordStmt) DotGraph() string {
graph := fmt.Sprintf(
`%#p[shape="box",label="%s = "];
%#p -> %x;
%s
}`,
node, node.Name,
node, reflect.ValueOf(node.Expr).Pointer(),
node.Expr.DotGraph(),
)
return graph
}
// DotGraph returns a DOT representation of // DotGraph returns a DOT representation of the record statement.
// DotGraph returns a DOT representation of a statement list.
func (es Expressions) DotGraph() string {
graph := ""
for _, expr := range es {
graph += expr.DotGraph()
}
return graph
}
// DotGraph returns a DOT representation of the vector aggregation.
func (node *AggregateExpr) DotGraph() string {
groupByStrings := make([]string, 0, len(node.Grouping))
for _, label := range node.Grouping {
groupByStrings = append(groupByStrings, string(label))
}
graph := fmt.Sprintf("%#p[label=\"%s BY (%s)\"]\n",
node,
node.Op,
strings.Join(groupByStrings, ", "))
graph += fmt.Sprintf("%#p -> %x;\n", node, reflect.ValueOf(node.Expr).Pointer())
graph += node.Expr.DotGraph()
return graph
}
// DotGraph returns a DOT representation of the expression.
func (node *BinaryExpr) DotGraph() string {
nodeAddr := reflect.ValueOf(node).Pointer()
graph := fmt.Sprintf(
`
%x[label="%s"];
%x -> %x;
%x -> %x;
%s
%s
}`,
nodeAddr, node.Op,
nodeAddr, reflect.ValueOf(node.LHS).Pointer(),
nodeAddr, reflect.ValueOf(node.RHS).Pointer(),
node.LHS.DotGraph(),
node.RHS.DotGraph(),
)
return graph
}
// DotGraph returns a DOT representation of the function call.
func (node *Call) DotGraph() string {
graph := fmt.Sprintf("%#p[label=\"%s\"];\n", node, node.Func.Name)
graph += functionArgsToDotGraph(node, node.Args)
return graph
}
// DotGraph returns a DOT representation of the number literal.
func (node *NumberLiteral) DotGraph() string {
return fmt.Sprintf("%#p[label=\"%v\"];\n", node, node.Val)
}
// DotGraph returns a DOT representation of the encapsulated expression.
func (node *ParenExpr) DotGraph() string {
return node.Expr.DotGraph()
}
// DotGraph returns a DOT representation of the matrix selector.
func (node *MatrixSelector) DotGraph() string {
return fmt.Sprintf("%#p[label=\"%s\"];\n", node, node)
}
// DotGraph returns a DOT representation of the string literal.
func (node *StringLiteral) DotGraph() string {
return fmt.Sprintf("%#p[label=\"'%q'\"];\n", node, node.Val)
}
// DotGraph returns a DOT representation of the unary expression.
func (node *UnaryExpr) DotGraph() string {
nodeAddr := reflect.ValueOf(node).Pointer()
graph := fmt.Sprintf(
`
%x[label="%s"];
%x -> %x;
%s
%s
}`,
nodeAddr, node.Op,
nodeAddr, reflect.ValueOf(node.Expr).Pointer(),
node.Expr.DotGraph(),
)
return graph
}
// DotGraph returns a DOT representation of the vector selector.
func (node *VectorSelector) DotGraph() string {
return fmt.Sprintf("%#p[label=\"%s\"];\n", node, node)
}
func functionArgsToDotGraph(node Node, args Expressions) string {
graph := args.DotGraph()
for _, arg := range args {
graph += fmt.Sprintf("%x -> %x;\n", reflect.ValueOf(node).Pointer(), reflect.ValueOf(arg).Pointer())
}
return graph
}

48
promql/printer_test.go Normal file
View File

@ -0,0 +1,48 @@
// Copyright 2015 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package promql
import (
"testing"
)
func TestExprString(t *testing.T) {
// A list of valid expressions that are expected to be
// returned as out when calling String(). If out is empty the output
// is expected to equal the input.
inputs := []struct {
in, out string
}{
{
in: `sum(task:errors:rate10s{job="s"}) BY (code)`,
},
{
in: `sum(task:errors:rate10s{job="s"}) BY (code) KEEPING_EXTRA`,
},
}
for _, test := range inputs {
expr, err := ParseExpr(test.in)
if err != nil {
t.Fatalf("parsing error for %q: %s", test.in, err)
}
exp := test.in
if test.out != "" {
exp = test.out
}
if expr.String() != exp {
t.Fatalf("expected %q to be returned as:\n%s\ngot:\n%s\n", test.in, exp, expr.String())
}
}
}