printer.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // Copyright 2015 The Prometheus Authors
  2. // Licensed under the Apache License, Version 2.0 (the "License");
  3. // you may not use this file except in compliance with the License.
  4. // You may obtain a copy of the License at
  5. //
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. package promql
  14. import (
  15. "fmt"
  16. "strings"
  17. "time"
  18. "github.com/influxdata/promql/v2/pkg/labels"
  19. "github.com/prometheus/common/model"
  20. )
  21. // Tree returns a string of the tree structure of the given node.
  22. func Tree(node Node) string {
  23. return tree(node, "")
  24. }
  25. func tree(node Node, level string) string {
  26. if node == nil {
  27. return fmt.Sprintf("%s |---- %T\n", level, node)
  28. }
  29. typs := strings.Split(fmt.Sprintf("%T", node), ".")[1]
  30. t := fmt.Sprintf("%s |---- %s :: %s\n", level, typs, node)
  31. level += " · · ·"
  32. switch n := node.(type) {
  33. case *EvalStmt:
  34. t += tree(n.Expr, level)
  35. case Expressions:
  36. for _, e := range n {
  37. t += tree(e, level)
  38. }
  39. case *AggregateExpr:
  40. t += tree(n.Expr, level)
  41. case *BinaryExpr:
  42. t += tree(n.LHS, level)
  43. t += tree(n.RHS, level)
  44. case *Call:
  45. t += tree(n.Args, level)
  46. case *ParenExpr:
  47. t += tree(n.Expr, level)
  48. case *UnaryExpr:
  49. t += tree(n.Expr, level)
  50. case *SubqueryExpr:
  51. t += tree(n.Expr, level)
  52. case *MatrixSelector, *NumberLiteral, *StringLiteral, *VectorSelector:
  53. // nothing to do
  54. default:
  55. panic("promql.Tree: not all node types covered")
  56. }
  57. return t
  58. }
  59. func (node *EvalStmt) String() string {
  60. return "EVAL " + node.Expr.String()
  61. }
  62. func (es Expressions) String() (s string) {
  63. if len(es) == 0 {
  64. return ""
  65. }
  66. for _, e := range es {
  67. s += e.String()
  68. s += ", "
  69. }
  70. return s[:len(s)-2]
  71. }
  72. func (node *AggregateExpr) String() string {
  73. aggrString := node.Op.String()
  74. if node.Without {
  75. aggrString += fmt.Sprintf(" without(%s) ", strings.Join(node.Grouping, ", "))
  76. } else {
  77. if len(node.Grouping) > 0 {
  78. aggrString += fmt.Sprintf(" by(%s) ", strings.Join(node.Grouping, ", "))
  79. }
  80. }
  81. aggrString += "("
  82. if node.Op.isAggregatorWithParam() {
  83. aggrString += fmt.Sprintf("%s, ", node.Param)
  84. }
  85. aggrString += fmt.Sprintf("%s)", node.Expr)
  86. return aggrString
  87. }
  88. func (node *BinaryExpr) String() string {
  89. returnBool := ""
  90. if node.ReturnBool {
  91. returnBool = " bool"
  92. }
  93. matching := ""
  94. vm := node.VectorMatching
  95. if vm != nil && (len(vm.MatchingLabels) > 0 || vm.On) {
  96. if vm.On {
  97. matching = fmt.Sprintf(" on(%s)", strings.Join(vm.MatchingLabels, ", "))
  98. } else {
  99. matching = fmt.Sprintf(" ignoring(%s)", strings.Join(vm.MatchingLabels, ", "))
  100. }
  101. if vm.Card == CardManyToOne || vm.Card == CardOneToMany {
  102. matching += " group_"
  103. if vm.Card == CardManyToOne {
  104. matching += "left"
  105. } else {
  106. matching += "right"
  107. }
  108. matching += fmt.Sprintf("(%s)", strings.Join(vm.Include, ", "))
  109. }
  110. }
  111. return fmt.Sprintf("%s %s%s%s %s", node.LHS, node.Op, returnBool, matching, node.RHS)
  112. }
  113. func (node *Call) String() string {
  114. return fmt.Sprintf("%s(%s)", node.Func.Name, node.Args)
  115. }
  116. func (node *MatrixSelector) String() string {
  117. vecSelector := &VectorSelector{
  118. Name: node.Name,
  119. LabelMatchers: node.LabelMatchers,
  120. }
  121. offset := ""
  122. if node.Offset != time.Duration(0) {
  123. offset = fmt.Sprintf(" offset %s", model.Duration(node.Offset))
  124. }
  125. return fmt.Sprintf("%s[%s]%s", vecSelector.String(), model.Duration(node.Range), offset)
  126. }
  127. func (node *SubqueryExpr) String() string {
  128. step := ""
  129. if node.Step != 0 {
  130. step = model.Duration(node.Step).String()
  131. }
  132. return fmt.Sprintf("%s[%s:%s]", node.Expr.String(), model.Duration(node.Range), step)
  133. }
  134. func (node *NumberLiteral) String() string {
  135. return fmt.Sprint(node.Val)
  136. }
  137. func (node *ParenExpr) String() string {
  138. return fmt.Sprintf("(%s)", node.Expr)
  139. }
  140. func (node *StringLiteral) String() string {
  141. return fmt.Sprintf("%q", node.Val)
  142. }
  143. func (node *UnaryExpr) String() string {
  144. return fmt.Sprintf("%s%s", node.Op, node.Expr)
  145. }
  146. func (node *VectorSelector) String() string {
  147. labelStrings := make([]string, 0, len(node.LabelMatchers)-1)
  148. for _, matcher := range node.LabelMatchers {
  149. // Only include the __name__ label if its equality matching and matches the name.
  150. if matcher.Name == labels.MetricName && matcher.Type == labels.MatchEqual && matcher.Value == node.Name {
  151. continue
  152. }
  153. labelStrings = append(labelStrings, matcher.String())
  154. }
  155. offset := ""
  156. if node.Offset != time.Duration(0) {
  157. offset = fmt.Sprintf(" offset %s", model.Duration(node.Offset))
  158. }
  159. if len(labelStrings) == 0 {
  160. return fmt.Sprintf("%s%s", node.Name, offset)
  161. }
  162. // sort.Strings(labelStrings)
  163. return fmt.Sprintf("%s{%s}%s", node.Name, strings.Join(labelStrings, ","), offset)
  164. }