1package querycheck
2
3import "fmt"
4
5type Plan struct {
6 NodeType string `json:"Node Type"`
7 ParallelAware bool `json:"Parallel Aware"`
8 AsyncCapable bool `json:"Async Capable"`
9 StartupCost float64 `json:"Startup Cost"`
10 TotalCost float64 `json:"Total Cost"`
11 PlanRows int `json:"Plan Rows"`
12 PlanWidth int `json:"Plan Width"`
13 ActualStartupTime float64 `json:"Actual Startup Time"`
14 ActualTotalTime float64 `json:"Actual Total Time"`
15 ActualRows int `json:"Actual Rows"`
16 ActualLoops int `json:"Actual Loops"`
17 Output []string `json:"Output"`
18 SharedHitBlocks int `json:"Shared Hit Blocks"`
19 SharedReadBlocks int `json:"Shared Read Blocks"`
20 SharedDirtiedBlocks int `json:"Shared Dirtied Blocks"`
21 SharedWrittenBlocks int `json:"Shared Written Blocks"`
22 LocalHitBlocks int `json:"Local Hit Blocks"`
23 LocalReadBlocks int `json:"Local Read Blocks"`
24 LocalDirtiedBlocks int `json:"Local Dirtied Blocks"`
25 LocalWrittenBlocks int `json:"Local Written Blocks"`
26 TempReadBlocks int `json:"Temp Read Blocks"`
27 TempWrittenBlocks int `json:"Temp Written Blocks"`
28 IOReadTime float64 `json:"I/O Read Time"`
29 IOWriteTime float64 `json:"I/O Write Time"`
30 Plans []Plan `json:"Plans,omitempty"`
31 ParentRelationship string `json:"Parent Relationship,omitempty"`
32 SortKey []string `json:"Sort Key,omitempty"`
33 SortMethod string `json:"Sort Method,omitempty"`
34 SortSpaceUsed int `json:"Sort Space Used,omitempty"`
35 SortSpaceType string `json:"Sort Space Type,omitempty"`
36 WorkersPlanned int `json:"Workers Planned,omitempty"`
37 WorkersLaunched int `json:"Workers Launched,omitempty"`
38 SingleCopy bool `json:"Single Copy,omitempty"`
39 RelationName string `json:"Relation Name,omitempty"`
40 Schema string `json:"Schema,omitempty"`
41 Alias string `json:"Alias,omitempty"`
42 Filter string `json:"Filter,omitempty"`
43 RowsRemovedByFilter int `json:"Rows Removed by Filter,omitempty"`
44 Workers []Worker `json:"Workers,omitempty"`
45}
46
47type Worker struct {
48 WorkerNumber int `json:"Worker Number"`
49 ActualStartupTime float64 `json:"Actual Startup Time"`
50 ActualTotalTime float64 `json:"Actual Total Time"`
51 ActualRows int `json:"Actual Rows"`
52 ActualLoops int `json:"Actual Loops"`
53 JIT JIT `json:"JIT"`
54 SharedHitBlocks int `json:"Shared Hit Blocks"`
55 SharedReadBlocks int `json:"Shared Read Blocks"`
56 SharedDirtiedBlocks int `json:"Shared Dirtied Blocks"`
57 SharedWrittenBlocks int `json:"Shared Written Blocks"`
58 LocalHitBlocks int `json:"Local Hit Blocks"`
59 LocalReadBlocks int `json:"Local Read Blocks"`
60 LocalDirtiedBlocks int `json:"Local Dirtied Blocks"`
61 LocalWrittenBlocks int `json:"Local Written Blocks"`
62 TempReadBlocks int `json:"Temp Read Blocks"`
63 TempWrittenBlocks int `json:"Temp Written Blocks"`
64 IOReadTime float64 `json:"I/O Read Time"`
65 IOWriteTime float64 `json:"I/O Write Time"`
66}
67
68type JIT struct {
69 Functions int `json:"Functions"`
70 Options Options `json:"Options"`
71 Timing Timing `json:"Timing"`
72}
73
74type Options struct {
75 Inlining bool `json:"Inlining"`
76 Optimization bool `json:"Optimization"`
77 Expressions bool `json:"Expressions"`
78 Deforming bool `json:"Deforming"`
79}
80
81type Timing struct {
82 Generation float64 `json:"Generation"`
83 Inlining float64 `json:"Inlining"`
84 Optimization float64 `json:"Optimization"`
85 Emission float64 `json:"Emission"`
86 Total float64 `json:"Total"`
87}
88
89type QueryPlan struct {
90 Plan Plan `json:"Plan"`
91 QueryIdentifier int64 `json:"Query Identifier"`
92 Planning Planning `json:"Planning"`
93 PlanningTime float64 `json:"Planning Time"`
94 Triggers []string `json:"Triggers"`
95 JIT JIT `json:"JIT"`
96 ExecutionTime float64 `json:"Execution Time"`
97}
98
99type Planning struct {
100 SharedHitBlocks int `json:"Shared Hit Blocks"`
101 SharedReadBlocks int `json:"Shared Read Blocks"`
102 SharedDirtiedBlocks int `json:"Shared Dirtied Blocks"`
103 SharedWrittenBlocks int `json:"Shared Written Blocks"`
104 LocalHitBlocks int `json:"Local Hit Blocks"`
105 LocalReadBlocks int `json:"Local Read Blocks"`
106 LocalDirtiedBlocks int `json:"Local Dirtied Blocks"`
107 LocalWrittenBlocks int `json:"Local Written Blocks"`
108 TempReadBlocks int `json:"Temp Read Blocks"`
109 TempWrittenBlocks int `json:"Temp Written Blocks"`
110 IOReadTime float64 `json:"I/O Read Time"`
111 IOWriteTime float64 `json:"I/O Write Time"`
112}
113
114type QueryPlans []QueryPlan
115
116func (q *QueryPlan) String() string {
117 ret := ""
118 ret += q.Plan.String(1)
119 return ret
120}
121
122func (p *Plan) String(i int) string {
123 ret := ""
124 ret += fmt.Sprintf("(%s) Timing: %fms | IO Read: %fms (H %d R %d D %d W %d) | IO Write: %fms",
125 p.NodeType,
126 p.ActualTotalTime,
127 p.IOReadTime,
128 p.SharedHitBlocks,
129 p.SharedReadBlocks,
130 p.SharedWrittenBlocks,
131 p.SharedDirtiedBlocks,
132 p.IOWriteTime,
133 )
134
135 for _, plan := range p.Plans {
136 ret += "\n"
137 for j := 0; j < i; j++ {
138 ret += "\t"
139 }
140 ret += plan.String(i + 1)
141 }
142
143 return ret
144}
145
146func (q *QueryPlan) HasSameStructureAs(other QueryPlan) bool {
147 return q.Plan.HasSameStructureAs(other.Plan)
148}
149
150func (p *Plan) HasSameStructureAs(other Plan) bool {
151 if p.NodeType != other.NodeType {
152 return false
153 }
154
155 if len(p.Plans) != len(other.Plans) {
156 return false
157 }
158
159 for i, plan := range p.Plans {
160 if !plan.HasSameStructureAs(other.Plans[i]) {
161 return false
162 }
163 }
164
165 return true
166}