cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.57.2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

cmd/pint/parse.go

130lines · modecode

1package main
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/prometheus/prometheus/promql/parser"
8 "github.com/urfave/cli/v2"
9)
10
11const levelStep = 2
12
13var parseCmd = &cli.Command{
14 Name: "parse",
15 Usage: "Parse a query and print AST, use it for debugging or understanding query details.",
16 Action: actionParse,
17}
18
19func printNode(ident int, format string, a ...interface{}) {
20 prefix := strings.Repeat(" ", ident)
21 fmt.Printf(prefix+format+"\n", a...)
22}
23
24func parseNode(node parser.Node, level int) {
25 printNode(level, "++ node: %v", node)
26 level += levelStep
27
28 switch n := node.(type) {
29 case parser.Expressions:
30 printNode(level, "Expressions:")
31 for _, e := range n {
32 parseNode(e, level+levelStep)
33 }
34 case *parser.AggregateExpr:
35 printNode(level, "AggregateExpr:")
36 level += levelStep
37 printNode(level, "* Type: %v", n.Type())
38 printNode(level, "* Op: %v", n.Op)
39 printNode(level, "* Expr: %v", n.Expr)
40 printNode(level, "* Param: %v", n.Param)
41 printNode(level, "* Grouping: %v", n.Grouping)
42 printNode(level, "* Without: %v", n.Without)
43 parseNode(n.Expr, level+levelStep)
44 case *parser.BinaryExpr:
45 printNode(level, "BinaryExpr:")
46 level += levelStep
47 printNode(level, "* Type: %v", n.Type())
48 printNode(level, "* Op: %v", n.Op)
49 printNode(level, "* LHS: %v", n.LHS)
50 printNode(level, "* RHS: %v", n.RHS)
51 printNode(level, "* VectorMatching:")
52 if n.VectorMatching != nil {
53 printNode(level+levelStep, "* Card: %v", n.VectorMatching.Card)
54 printNode(level+levelStep, "* MatchingLabels: %v", n.VectorMatching.MatchingLabels)
55 printNode(level+levelStep, "* On: %v", n.VectorMatching.On)
56 printNode(level+levelStep, "* Include: %v", n.VectorMatching.Include)
57 }
58 printNode(level, "* ReturnBool: %v", n.ReturnBool)
59 parseNode(n.LHS, level+levelStep)
60 parseNode(n.RHS, level+levelStep)
61 case *parser.Call:
62 printNode(level, "Call:")
63 level += levelStep
64 printNode(level, "* Type: %v", n.Type())
65 printNode(level, "* Func: %v", n.Func.Name)
66 printNode(level, "* Args: %v", n.Args)
67 parseNode(n.Args, level+levelStep)
68 case *parser.ParenExpr:
69 printNode(level, "ParenExpr:")
70 level += levelStep
71 printNode(level, "* Type: %v", n.Type())
72 printNode(level, "* Expr: %v", n.Expr)
73 parseNode(n.Expr, level+levelStep)
74 case *parser.SubqueryExpr:
75 printNode(level, "SubqueryExpr:")
76 level += levelStep
77 printNode(level, "* Type: %v", n.Type())
78 printNode(level, "* Expr: %v", n.Expr)
79 printNode(level, "* Step: %v", n.Step)
80 printNode(level, "* Range: %v", n.Range)
81 printNode(level, "* Offset: %v", n.Offset)
82 parseNode(n.Expr, level+levelStep)
83 case *parser.MatrixSelector:
84 printNode(level, "MatrixSelector:")
85 level += levelStep
86 printNode(level, "* Type: %v", n.Type())
87 printNode(level, "* VectorSelector: %v", n.VectorSelector)
88 printNode(level, "* Range: %v", n.Range)
89 case *parser.VectorSelector:
90 printNode(level, "VectorSelector:")
91 level += levelStep
92 printNode(level, "* Type: %v", n.Type())
93 printNode(level, "* Name: %v", n.Name)
94 printNode(level, "* Offset: %v", n.Offset)
95 printNode(level, "* LabelMatchers: %v", n.LabelMatchers)
96 case *parser.NumberLiteral:
97 printNode(level, "NumberLiteral:")
98 level += levelStep
99 printNode(level, "* Type: %v", n.Type())
100 case *parser.StringLiteral:
101 printNode(level, "StringLiteral:")
102 level += levelStep
103 printNode(level, "* Type: %v", n.Type())
104 default:
105 printNode(level, "! Unsupported node")
106 }
107}
108
109func parseQuery(query string) error {
110 expr, err := parser.ParseExpr(query)
111 if err != nil {
112 return err
113 }
114 parseNode(expr, 0)
115 return nil
116}
117
118func actionParse(c *cli.Context) (err error) {
119 err = initLogger(c.String(logLevelFlag), c.Bool(noColorFlag))
120 if err != nil {
121 return fmt.Errorf("failed to set log level: %w", err)
122 }
123
124 parts := c.Args().Slice()
125 if len(parts) == 0 {
126 return fmt.Errorf("a query string is required")
127 }
128 query := strings.Join(parts, " ")
129 return parseQuery(query)
130}