-
Notifications
You must be signed in to change notification settings - Fork 125
/
Copy pathprofiling.go
64 lines (53 loc) · 2.04 KB
/
profiling.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package duckdb
import (
"database/sql"
"github.com/marcboeker/go-duckdb/mapping"
)
// ProfilingInfo is a recursive type containing metrics for each node in DuckDB's query plan.
// There are two types of nodes: the QUERY_ROOT and OPERATOR nodes.
// The QUERY_ROOT refers exclusively to the top-level node; its metrics are measured over the entire query.
// The OPERATOR nodes refer to the individual operators in the query plan.
type ProfilingInfo struct {
// Metrics contains all key-value pairs of the current node.
// The key represents the name and corresponds to the measured value.
Metrics map[string]string
// Children contains all children of the node and their respective metrics.
Children []ProfilingInfo
}
// GetProfilingInfo obtains all available metrics set by the current connection.
func GetProfilingInfo(c *sql.Conn) (ProfilingInfo, error) {
info := ProfilingInfo{}
err := c.Raw(func(driverConn any) error {
conn := driverConn.(*Conn)
profilingInfo := mapping.GetProfilingInfo(conn.conn)
if profilingInfo.Ptr == nil {
return getError(errProfilingInfoEmpty, nil)
}
// Recursive tree traversal.
info.getMetrics(profilingInfo)
return nil
})
return info, err
}
func (info *ProfilingInfo) getMetrics(profilingInfo mapping.ProfilingInfo) {
metricsMap := mapping.ProfilingInfoGetMetrics(profilingInfo)
count := mapping.GetMapSize(metricsMap)
info.Metrics = make(map[string]string, count)
for i := mapping.IdxT(0); i < count; i++ {
key := mapping.GetMapKey(metricsMap, i)
value := mapping.GetMapValue(metricsMap, i)
keyStr := mapping.GetVarchar(key)
valueStr := mapping.GetVarchar(value)
info.Metrics[keyStr] = valueStr
mapping.DestroyValue(&key)
mapping.DestroyValue(&value)
}
mapping.DestroyValue(&metricsMap)
childCount := mapping.ProfilingInfoGetChildCount(profilingInfo)
for i := mapping.IdxT(0); i < childCount; i++ {
profilingInfoChild := mapping.ProfilingInfoGetChild(profilingInfo, i)
childInfo := ProfilingInfo{}
childInfo.getMetrics(profilingInfoChild)
info.Children = append(info.Children, childInfo)
}
}