mirror of
https://github.com/hanzoai/traces.git
synced 2026-10-30 18:20:41 +00:00
* Add operators IN, NOT IN, MATCH ANY, and MATCH NONE
* Implement Static.append()
* Print string arrays with '`' instead of '"'
Example ["aa", "bb"] -> [`aa`, `bb`]
* Rewrite binary operations to array equivalent
The rewriter handles the following cases:
- { .a = "a" || .a = "b" } => { .a IN ["a", "b"] }
- { .a != "a" && .a != "b" } => { .a NOT IN ["a", "b"] }
- { .a =~ "a" || .a =~ "b" } => { .a MATCH ANY ["a", "b"] }
- { .a !~ "a" && .a !~ "b" } => { .a MATCH NONE ["a", "b"] }
* Add test cases with arrays to TestBinOp
* traceql.Parse() applies AST optimizations by default
* Rename predicate_test.go to predicates_test.go
* Add array predicates to parquetquery
* BREAKING CHANGE: more precise regex validation
BinaryOperation.validate() considered everythin a valid regex where
FieldExpression.EncodeToString(false) happened to return a valid regex.
With this change the RHS of a regex operation is required to be a string
or string array
* vp4: handle predicates with arrays correctly
* vp5: handle predicates with arrays correctly
* vp3: handle predicates with arrays correctly
* Add test cases for optimized queries
* Update query test examples with optimizable queries
* vp3: fix handling of array types
* CHANGELOG.md
* Pass array operators down to fetch layer
* Read to first virtual row after seeking on a low definition level
This helps avoid additional spans/op in queries with only
resource attributes
---------
Co-authored-by: Martin Disibio <[email protected]>
112 lines
2.6 KiB
Go
112 lines
2.6 KiB
Go
package traceql
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// The list of all traceql query hints. Although most of these are implementation-specific
|
|
// and not part of the language or engine, we organize them here in one place.
|
|
const (
|
|
HintSample = "sample"
|
|
HintTraceSample = "trace_sample"
|
|
HintSpanSample = "span_sample"
|
|
HintJobSize = "job_size"
|
|
HintTimeOverlapCutoff = "time_overlap_cutoff"
|
|
HintConcurrentBlocks = "concurrent_blocks"
|
|
HintExemplars = "exemplars"
|
|
HintMostRecent = "most_recent" // traceql search hint to return most recent results ordered by time
|
|
HintDebug = "debug"
|
|
HintInfo = "info"
|
|
HintDebugReturnIn = "debug_return_in" // performance testing hint to simulate query latency and return fake data
|
|
HintDebugStdDev = "debug_std_dev" // standard deviation for debug_return_in latency simulation
|
|
HintDebugDataFactor = "debug_data_factor" // performance testing hint to control the possibility of non-empty fake data
|
|
HintSkipOptimization = "skip_optimization" // don't apply AST optimizations
|
|
)
|
|
|
|
func isUnsafe(h string) bool {
|
|
switch h {
|
|
case HintSample, HintTraceSample, HintSpanSample, HintExemplars, HintMostRecent, HintSkipOptimization:
|
|
return false
|
|
default:
|
|
return true
|
|
}
|
|
}
|
|
|
|
type Hint struct {
|
|
Name string
|
|
Value Static
|
|
}
|
|
|
|
func newHint(k string, v Static) *Hint {
|
|
return &Hint{k, v}
|
|
}
|
|
|
|
type Hints struct {
|
|
Hints []*Hint
|
|
}
|
|
|
|
func newHints(h []*Hint) *Hints {
|
|
return &Hints{h}
|
|
}
|
|
|
|
func (h *Hints) GetFloat(k string, allowUnsafe bool) (v float64, ok bool) {
|
|
if v, ok := h.Get(k, TypeFloat, allowUnsafe); ok {
|
|
return v.Float(), ok
|
|
}
|
|
|
|
// If float not found, then try integer.
|
|
if v, ok := h.Get(k, TypeInt, allowUnsafe); ok {
|
|
n, _ := v.Int()
|
|
return float64(n), ok
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (h *Hints) GetInt(k string, allowUnsafe bool) (v int, ok bool) {
|
|
if v, ok := h.Get(k, TypeInt, allowUnsafe); ok {
|
|
n, _ := v.Int()
|
|
return n, ok
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (h *Hints) GetDuration(k string, allowUnsafe bool) (v time.Duration, ok bool) {
|
|
if v, ok := h.Get(k, TypeDuration, allowUnsafe); ok {
|
|
d, _ := v.Duration()
|
|
return d, ok
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (h *Hints) GetBool(k string, allowUnsafe bool) (v, ok bool) {
|
|
if v, ok := h.Get(k, TypeBoolean, allowUnsafe); ok {
|
|
b, _ := v.Bool()
|
|
return b, ok
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (h *Hints) Get(k string, t StaticType, allowUnsafe bool) (v Static, ok bool) {
|
|
if h == nil {
|
|
return
|
|
}
|
|
|
|
if isUnsafe(k) && !allowUnsafe {
|
|
return
|
|
}
|
|
|
|
for _, hh := range h.Hints {
|
|
if hh.Name == k && hh.Value.Type == t {
|
|
return hh.Value, true
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
var _ Element = (*Hints)(nil)
|