diff --git a/pkg/traceql/ast.go b/pkg/traceql/ast.go index 41fd2d2c5a6..9f5a34ca60b 100644 --- a/pkg/traceql/ast.go +++ b/pkg/traceql/ast.go @@ -933,15 +933,18 @@ type Attribute struct { Parent bool Name string Intrinsic Intrinsic + IsArray bool } // NewAttribute creates a new attribute with the given identifier string. -func NewAttribute(att string) Attribute { +// this is same as NewScopedAttribute(AttributeScopeNone, false, att), so maybe we remove this method?? +func NewAttribute(att string, isArray bool) Attribute { return Attribute{ Scope: AttributeScopeNone, Parent: false, Name: att, Intrinsic: IntrinsicNone, + IsArray: isArray, } } @@ -999,7 +1002,7 @@ func (Attribute) referencesSpan() bool { // NewScopedAttribute creates a new scopedattribute with the given identifier string. // this handles parent, span, and resource scopes. -func NewScopedAttribute(scope AttributeScope, parent bool, att string) Attribute { +func NewScopedAttribute(scope AttributeScope, parent bool, att string, isArray bool) Attribute { intrinsic := IntrinsicNone // if we are explicitly passed a resource or span scopes then we shouldn't parse for intrinsic if scope == AttributeScopeNone && !parent { @@ -1011,6 +1014,7 @@ func NewScopedAttribute(scope AttributeScope, parent bool, att string) Attribute Parent: parent, Name: att, Intrinsic: intrinsic, + IsArray: isArray, } } diff --git a/pkg/traceql/ast_conditions_test.go b/pkg/traceql/ast_conditions_test.go index 1cd7ddf29bb..ac380fc92c0 100644 --- a/pkg/traceql/ast_conditions_test.go +++ b/pkg/traceql/ast_conditions_test.go @@ -16,16 +16,16 @@ func TestSpansetFilter_extractConditions(t *testing.T) { { query: `{ .foo = "bar" && "bzz" = .fzz }`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("bar")), - newCondition(NewAttribute("fzz"), OpEqual, NewStaticString("bzz")), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("bar")), + newCondition(NewAttribute("fzz", false), OpEqual, NewStaticString("bzz")), }, allConditions: true, }, { query: `{ .foo = "bar" || "bzz" = .fzz }`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("bar")), - newCondition(NewAttribute("fzz"), OpEqual, NewStaticString("bzz")), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("bar")), + newCondition(NewAttribute("fzz", false), OpEqual, NewStaticString("bzz")), }, allConditions: false, }, @@ -37,38 +37,38 @@ func TestSpansetFilter_extractConditions(t *testing.T) { { query: `{ .foo = .bar }`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpNone), - newCondition(NewAttribute("bar"), OpNone), + newCondition(NewAttribute("foo", false), OpNone), + newCondition(NewAttribute("bar", false), OpNone), }, allConditions: true, }, { query: `{ (.foo = "bar") = true }`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("bar")), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("bar")), }, allConditions: true, }, { query: `{ true = (.foo = "bar") }`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("bar")), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("bar")), }, allConditions: true, }, { query: `{ (.foo = "bar") = .bar }`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("bar")), - newCondition(NewAttribute("bar"), OpNone), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("bar")), + newCondition(NewAttribute("bar", false), OpNone), }, allConditions: true, }, { query: `{ .bar = (.foo = "bar") }`, conditions: []Condition{ - newCondition(NewAttribute("bar"), OpNone), - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("bar")), + newCondition(NewAttribute("bar", false), OpNone), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("bar")), }, allConditions: true, }, @@ -84,24 +84,24 @@ func TestSpansetFilter_extractConditions(t *testing.T) { { query: `{ (.foo = "bar") = !.bar }`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("bar")), - newCondition(NewAttribute("bar"), OpNone), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("bar")), + newCondition(NewAttribute("bar", false), OpNone), }, allConditions: true, }, { query: `{ .foo = .bar + 1 }`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpNone), - newCondition(NewAttribute("bar"), OpNone), + newCondition(NewAttribute("foo", false), OpNone), + newCondition(NewAttribute("bar", false), OpNone), }, allConditions: true, }, { query: `{ (.foo = 2) && (.bar / 1 > 3) }`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticInt(2)), - newCondition(NewAttribute("bar"), OpNone), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticInt(2)), + newCondition(NewAttribute("bar", false), OpNone), }, allConditions: true, }, @@ -135,14 +135,14 @@ func TestScalarFilter_extractConditions(t *testing.T) { { query: `{ .foo = "a" } | count() > 10`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("a")), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("a")), }, allConditions: false, }, { query: `{ .foo = "a" } | avg(duration) > 10ms`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("a")), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("a")), newCondition(NewIntrinsic(IntrinsicDuration), OpNone), }, allConditions: false, @@ -225,10 +225,10 @@ func TestSelect_extractConditions(t *testing.T) { { query: `{ .foo = "a" } | select(resource.service.name)`, conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("a")), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("a")), }, secondPassConditions: []Condition{ - newCondition(NewScopedAttribute(AttributeScopeResource, false, "service.name"), OpNone), + newCondition(NewScopedAttribute(AttributeScopeResource, false, "service.name", false), OpNone), }, allConditions: false, }, @@ -238,7 +238,7 @@ func TestSelect_extractConditions(t *testing.T) { newCondition(NewIntrinsic(IntrinsicSpanStartTime), OpNone), }, secondPassConditions: []Condition{ - newCondition(NewAttribute("name"), OpNone), + newCondition(NewAttribute("name", false), OpNone), newCondition(NewIntrinsic(IntrinsicName), OpNone), }, allConditions: false, diff --git a/pkg/traceql/ast_execute_test.go b/pkg/traceql/ast_execute_test.go index 4a2345a96b2..3dad7bc7ec3 100644 --- a/pkg/traceql/ast_execute_test.go +++ b/pkg/traceql/ast_execute_test.go @@ -66,8 +66,8 @@ func TestSpansetFilter_matches(t *testing.T) { query: `{ .foo = .bar }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("bzz"), - NewAttribute("bar"): NewStaticString("bzz"), + NewAttribute("foo", false): NewStaticString("bzz"), + NewAttribute("bar", false): NewStaticString("bzz"), }, }, matches: true, @@ -77,7 +77,7 @@ func TestSpansetFilter_matches(t *testing.T) { query: `{ .foo = "bar" }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("fzz"): NewStaticString("bar"), + NewAttribute("fzz", false): NewStaticString("bar"), }, }, matches: false, @@ -86,8 +86,8 @@ func TestSpansetFilter_matches(t *testing.T) { query: `{ .foo = .bar }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("str"), - NewAttribute("bar"): NewStaticInt(5), + NewAttribute("foo", false): NewStaticString("str"), + NewAttribute("bar", false): NewStaticInt(5), }, }, matches: false, @@ -97,8 +97,8 @@ func TestSpansetFilter_matches(t *testing.T) { query: `{ .foo =~ .bar }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticInt(3), - NewAttribute("bar"): NewStaticInt(5), + NewAttribute("foo", false): NewStaticInt(3), + NewAttribute("bar", false): NewStaticInt(5), }, }, matches: false, @@ -107,8 +107,8 @@ func TestSpansetFilter_matches(t *testing.T) { query: `{ .field1 =~ "hello w.*" && .field2 !~ "bye b.*" }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("field1"): NewStaticString("hello world"), - NewAttribute("field2"): NewStaticString("bye world"), + NewAttribute("field1", false): NewStaticString("hello world"), + NewAttribute("field2", false): NewStaticString("bye world"), }, }, matches: true, @@ -117,8 +117,8 @@ func TestSpansetFilter_matches(t *testing.T) { query: `{ .foo > 2 && .foo >= 3.5 && .foo < 5 && .foo <= 3.5 && .duration > 1800ms }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticFloat(3.5), - NewAttribute("duration"): NewStaticDuration(2 * time.Second), + NewAttribute("foo", false): NewStaticFloat(3.5), + NewAttribute("duration", false): NewStaticDuration(2 * time.Second), }, }, matches: true, @@ -127,8 +127,8 @@ func TestSpansetFilter_matches(t *testing.T) { query: `{ .foo = "scope_span" }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewScopedAttribute(AttributeScopeSpan, false, "foo"): NewStaticString("scope_span"), - NewScopedAttribute(AttributeScopeResource, false, "foo"): NewStaticString("scope_resource"), + NewScopedAttribute(AttributeScopeSpan, false, "foo", false): NewStaticString("scope_span"), + NewScopedAttribute(AttributeScopeResource, false, "foo", false): NewStaticString("scope_resource"), }, }, matches: true, @@ -137,7 +137,7 @@ func TestSpansetFilter_matches(t *testing.T) { query: `{ .foo = "scope_resource" }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewScopedAttribute(AttributeScopeResource, false, "foo"): NewStaticString("scope_resource"), + NewScopedAttribute(AttributeScopeResource, false, "foo", false): NewStaticString("scope_resource"), }, }, matches: true, @@ -146,8 +146,8 @@ func TestSpansetFilter_matches(t *testing.T) { query: `{ span.foo = "scope_span" }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewScopedAttribute(AttributeScopeSpan, false, "foo"): NewStaticString("scope_span"), - NewScopedAttribute(AttributeScopeResource, false, "foo"): NewStaticString("scope_resource"), + NewScopedAttribute(AttributeScopeSpan, false, "foo", false): NewStaticString("scope_span"), + NewScopedAttribute(AttributeScopeResource, false, "foo", false): NewStaticString("scope_resource"), }, }, matches: true, @@ -156,8 +156,8 @@ func TestSpansetFilter_matches(t *testing.T) { query: `{ resource.foo = "scope_resource" }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewScopedAttribute(AttributeScopeSpan, false, "foo"): NewStaticString("scope_span"), - NewScopedAttribute(AttributeScopeResource, false, "foo"): NewStaticString("scope_resource"), + NewScopedAttribute(AttributeScopeSpan, false, "foo", false): NewStaticString("scope_span"), + NewScopedAttribute(AttributeScopeResource, false, "foo", false): NewStaticString("scope_resource"), }, }, matches: true, @@ -185,22 +185,22 @@ func TestGroup(t *testing.T) { "{ } | by(.foo)", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, }, []*Spanset{ { Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }, Attributes: []*SpansetAttribute{{Name: "by(.foo)", Val: NewStaticString("a")}}, }, { Spans: []Span{ - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }, Attributes: []*SpansetAttribute{{Name: "by(.foo)", Val: NewStaticString("b")}}, }, @@ -210,27 +210,27 @@ func TestGroup(t *testing.T) { "{ } | by(.foo) | by(.bar)", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a"), NewAttribute("bar"): NewStaticString("1")}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b"), NewAttribute("bar"): NewStaticString("1")}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b"), NewAttribute("bar"): NewStaticString("2")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a"), NewAttribute("bar", false): NewStaticString("1")}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b"), NewAttribute("bar", false): NewStaticString("1")}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b"), NewAttribute("bar", false): NewStaticString("2")}}, }}, }, []*Spanset{ { Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a"), NewAttribute("bar"): NewStaticString("1")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a"), NewAttribute("bar", false): NewStaticString("1")}}, }, Attributes: []*SpansetAttribute{{Name: "by(.foo)", Val: NewStaticString("a")}, {Name: "by(.bar)", Val: NewStaticString("1")}}, }, { Spans: []Span{ - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b"), NewAttribute("bar"): NewStaticString("1")}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b"), NewAttribute("bar", false): NewStaticString("1")}}, }, Attributes: []*SpansetAttribute{{Name: "by(.foo)", Val: NewStaticString("b")}, {Name: "by(.bar)", Val: NewStaticString("1")}}, }, { Spans: []Span{ - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b"), NewAttribute("bar"): NewStaticString("2")}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b"), NewAttribute("bar", false): NewStaticString("2")}}, }, Attributes: []*SpansetAttribute{{Name: "by(.foo)", Val: NewStaticString("b")}, {Name: "by(.bar)", Val: NewStaticString("2")}}, }, @@ -249,12 +249,12 @@ func TestCoalesce(t *testing.T) { "{ } | coalesce()", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }}, { Spans: []Span{ - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }, // coalesce() should drop attributes Attributes: []*SpansetAttribute{{Name: "by(.foo)", Val: NewStaticString("a")}}, @@ -262,9 +262,9 @@ func TestCoalesce(t *testing.T) { }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, }, }, @@ -282,18 +282,18 @@ func TestSpansetOperationEvaluate(t *testing.T) { []*Spanset{ {Spans: []Span{ // This spanset will be kept because it satisfies both conditions - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, {Spans: []Span{ // This spanset will be dropped - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }}, }, }, @@ -301,22 +301,22 @@ func TestSpansetOperationEvaluate(t *testing.T) { "{ .foo = `a` } || { .foo = `b` }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, {Spans: []Span{ // Second span will be dropped - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, - &mockSpan{id: []byte{4}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("c")}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, + &mockSpan{id: []byte{4}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("c")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }}, {Spans: []Span{ - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, }, }, @@ -324,12 +324,12 @@ func TestSpansetOperationEvaluate(t *testing.T) { "{ true } && { true } && { true }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }}, }, }, @@ -337,12 +337,12 @@ func TestSpansetOperationEvaluate(t *testing.T) { "{ true } || { true } || { true }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }}, }, }, @@ -536,13 +536,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = `bar` }", // match string array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, }}, }, }, @@ -550,13 +550,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = `bar` || .bat = `baz` }", // match string array with or []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, }}, }, }, @@ -564,13 +564,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo != `baz` }", // match string array not equal []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"baz"})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, }}, }, }, @@ -578,15 +578,15 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo =~ `ba` }", // match string array with regex []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"foo", "baz"})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"dog", "cat"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"foo", "baz"})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"dog", "cat"})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"foo", "baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"foo", "baz"})}}, }}, }, }, @@ -594,15 +594,15 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo !~ `ba` }", // regex non-matching []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"foo", "baz"})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"cat"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"foo", "baz"})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"cat"})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"foo", "baz"})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"cat"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"foo", "baz"})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"cat"})}}, }}, }, }, @@ -611,13 +611,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = 2 }", // match int array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, }}, }, }, @@ -625,16 +625,16 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo != 3 }", // match int array not equal []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 4})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 4})}}, // this is filtered out as expected?? - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 3})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 3})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 4})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 4})}}, }}, }, }, @@ -642,13 +642,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = 2.5 }", // match float array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 2.5})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 2.5})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 2.5})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 2.5})}}, }}, }, }, @@ -656,13 +656,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = 3.14 }", // match another float array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{3.14, 6.28})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.23, 4.56})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{3.14, 6.28})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.23, 4.56})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{3.14, 6.28})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{3.14, 6.28})}}, }}, }, }, @@ -670,13 +670,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo > 1 }", // match int array greater than []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{0, 1})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{0, 1})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, }}, }, }, @@ -684,15 +684,15 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo >= 1 }", // match int array greater equal than []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{0, 1})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{0, -1})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{0, 1})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{0, -1})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{0, 1})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{0, 1})}}, }}, }, }, @@ -700,13 +700,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo < 2 }", // match int array less than []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 3})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 4})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 3})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 4})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 3})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 3})}}, }}, }, }, @@ -714,15 +714,15 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo <= 2 }", // match int array less than equal []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 3})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 4})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{2, 4})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 3})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 4})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{2, 4})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 3})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{2, 4})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 3})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{2, 4})}}, }}, }, }, @@ -731,15 +731,15 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo != 2.5 }", // match float array not equal []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.0})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.5, 4.0})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.5})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.5, 4.0})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.5})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.0})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.5, 4.0})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.5, 4.0})}}, }}, }, }, @@ -747,13 +747,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo < 2.0 }", // match float array less than []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.0})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 4.0})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 4.0})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.0})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.0})}}, }}, }, }, @@ -761,15 +761,15 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo <= 2.0 }", // match float array less than []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.0})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 4.0})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{3.0, 4.0})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 4.0})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{3.0, 4.0})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.0})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 4.0})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 4.0})}}, }}, }, }, @@ -777,13 +777,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo > 2.5 }", // match float array greater than []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 3.0})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.0, 2.0})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 3.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.0, 2.0})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 3.0})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 3.0})}}, }}, }, }, @@ -791,15 +791,15 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo >= 2.5 }", // match float array greater than []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 3.0})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.0, 2.0})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.0, 2.5})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 3.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.0, 2.0})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.0, 2.5})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 3.0})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.0, 2.5})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 3.0})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.0, 2.5})}}, }}, }, }, @@ -808,13 +808,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = true }", // match boolean array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, }}, }, }, @@ -822,13 +822,13 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = false }", // match another boolean array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, }}, }, }, @@ -836,15 +836,15 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo != true }", // match boolean array not equal to true []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, }}, }, }, @@ -852,15 +852,15 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = !true }", // match boolean array not equal to true []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, }}, }, }, @@ -868,14 +868,14 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = true && .foo = false }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, }}, }, }, @@ -883,16 +883,16 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = true || .foo = false }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, }}, }, }, @@ -901,7 +901,7 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = 1 }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{})}}, }}, }, []*Spanset{}, @@ -910,7 +910,7 @@ func TestSpansetOperationEvaluateArray(t *testing.T) { "{ .foo = `test` }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{})}}, }}, }, []*Spanset{}, @@ -929,12 +929,12 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ `bar` = .foo }", // Symmetric match for string array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, }}, }, }, @@ -942,13 +942,13 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ `baz` != .foo }", // Symmetric not equal for string array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"baz"})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, }}, }, }, @@ -956,15 +956,15 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ `ba` =~ .foo }", // Symmetric regex match for string array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"foo", "baz"})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"cat", "dog"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"foo", "baz"})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"cat", "dog"})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"foo", "baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"foo", "baz"})}}, }}, }, }, @@ -972,13 +972,13 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ `ba` !~ .foo }", // Symmetric regex non-match for string array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"foo", "baz"})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"bar", "baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"foo", "baz"})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"bar", "baz"})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticStringArray([]string{"foo", "baz"})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticStringArray([]string{"foo", "baz"})}}, }}, }, }, @@ -987,12 +987,12 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 2 = .foo }", // Symmetric match for int array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, }}, }, }, @@ -1000,15 +1000,15 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 3 != .foo }", // Symmetric not equal for int array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 4})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 4})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 4})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 4})}}, }}, }, }, @@ -1016,15 +1016,15 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 2 < .foo }", // Symmetric less-than for int array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{0, 1})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{0, 1})}}, }}, }, []*Spanset{ {Spans: []Span{ // spans with any array elements grater then 2 will not be filtered out. - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 2})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 2})}}, }}, }, }, @@ -1032,15 +1032,15 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 2 <= .foo }", // Symmetric less-than equal for int array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{0, 1})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{0, 1})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 2})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 2})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, }}, }, }, @@ -1048,13 +1048,13 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 3 > .foo }", // Symmetric grater-than for int array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 3})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 4})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 3})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 4})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 3})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 3})}}, }}, }, }, @@ -1062,17 +1062,17 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 3 >= .foo }", // Symmetric grater-than-equal for int array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 3})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 4})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, - &mockSpan{id: []byte{4}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{4, 6})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 3})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 4})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{4}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{4, 6})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 3})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{3, 4})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 3})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{3, 4})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, }}, }, }, @@ -1081,13 +1081,13 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 2.5 = .foo }", // Symmetric match for float array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 2.5})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.5})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 2.5})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.5})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 2.5})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 2.5})}}, }}, }, }, @@ -1095,15 +1095,15 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 3.14 != .foo }", // Symmetric not equal for float array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.23, 4.56})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{3.14, 6.28})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{3.14})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.23, 4.56})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{3.14, 6.28})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{3.14})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.23, 4.56})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{3.14, 6.28})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.23, 4.56})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{3.14, 6.28})}}, }}, }, }, @@ -1111,13 +1111,13 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 2.0 > .foo }", // Symmetric grater-than for float array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 4.0})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.0})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 4.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.0})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.0})}}, }}, }, }, @@ -1125,15 +1125,15 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 2.0 >= .foo }", // Symmetric grater-than-equal for float array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 4.0})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.0})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{3.5, 3.0})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 4.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.0})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{3.5, 3.0})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 4.0})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{1.5, 3.0})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 4.0})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{1.5, 3.0})}}, }}, }, }, @@ -1141,15 +1141,15 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 3.5 < .foo }", // Symmetric less-than for float array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 3.5})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{4.0, 3.5})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{4.0, 5.5})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 3.5})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{4.0, 3.5})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{4.0, 5.5})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{4.0, 3.5})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{4.0, 5.5})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{4.0, 3.5})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{4.0, 5.5})}}, }}, }, }, @@ -1157,17 +1157,17 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ 3.5 <= .foo }", // Symmetric less-than-equal for float array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 3.5})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{4.0, 3.5})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{4.0, 5.5})}}, - &mockSpan{id: []byte{4}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 1.5})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 3.5})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{4.0, 3.5})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{4.0, 5.5})}}, + &mockSpan{id: []byte{4}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 1.5})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{2.0, 3.5})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{4.0, 3.5})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloatArray([]float64{4.0, 5.5})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{2.0, 3.5})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{4.0, 3.5})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloatArray([]float64{4.0, 5.5})}}, }}, }, }, @@ -1176,12 +1176,12 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ true = .foo }", // Symmetric match for boolean array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, }}, }, }, @@ -1189,15 +1189,15 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ false != .foo }", // Symmetric not equal for boolean array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, }}, }, }, @@ -1205,15 +1205,15 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ !false = .foo }", // Symmetric not equal for boolean array []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, }}, }, }, @@ -1221,14 +1221,14 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ true = .foo && false = .foo }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, }}, }, }, @@ -1236,16 +1236,16 @@ func TestSpansetOperationEvaluateArraySymmetric(t *testing.T) { "{ true = .foo || false = .foo }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, false})}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{true, true})}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticBooleanArray([]bool{false, false})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, false})}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{true, true})}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticBooleanArray([]bool{false, false})}}, }}, }, }, @@ -1261,7 +1261,7 @@ func TestSpansetOperationEvaluateArrayUnsupported(t *testing.T) { "{ .foo + 3 = 4 }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, }}, }, []*Spanset{}, @@ -1270,7 +1270,7 @@ func TestSpansetOperationEvaluateArrayUnsupported(t *testing.T) { "{ 4 = .foo + 3 }", []*Spanset{ {Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticIntArray([]int{1, 2})}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticIntArray([]int{1, 2})}}, }}, }, []*Spanset{}, @@ -1303,21 +1303,21 @@ func TestScalarFilterEvaluate(t *testing.T) { []*Spanset{ {Spans: []Span{ // This has 1 match - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, {Spans: []Span{ // This has 2 matches - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }}, }, []*Spanset{ { Scalar: NewStaticInt(2), Spans: []Span{ - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }, Attributes: []*SpansetAttribute{{Name: "count()", Val: NewStaticInt(2)}}, }, @@ -1330,13 +1330,13 @@ func TestScalarFilterEvaluate(t *testing.T) { // Avg duration = 5ms &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(2 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(8 * time.Millisecond), }, }, @@ -1345,13 +1345,13 @@ func TestScalarFilterEvaluate(t *testing.T) { // Avg duration = 10ms &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(5 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(15 * time.Millisecond), }, }, @@ -1363,13 +1363,13 @@ func TestScalarFilterEvaluate(t *testing.T) { Spans: []Span{ &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(5 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(15 * time.Millisecond), }, }, @@ -1386,13 +1386,13 @@ func TestScalarFilterEvaluate(t *testing.T) { // max duration = 8ms &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(2 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(8 * time.Millisecond), }, }, @@ -1401,13 +1401,13 @@ func TestScalarFilterEvaluate(t *testing.T) { // max duration = 15ms &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(5 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(15 * time.Millisecond), }, }, @@ -1419,13 +1419,13 @@ func TestScalarFilterEvaluate(t *testing.T) { Spans: []Span{ &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(5 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(15 * time.Millisecond), }, }, @@ -1442,13 +1442,13 @@ func TestScalarFilterEvaluate(t *testing.T) { // min duration = 2ms &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(2 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(8 * time.Millisecond), }, }, @@ -1457,13 +1457,13 @@ func TestScalarFilterEvaluate(t *testing.T) { // min duration = 5ms &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(12 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(15 * time.Millisecond), }, }, @@ -1475,13 +1475,13 @@ func TestScalarFilterEvaluate(t *testing.T) { Spans: []Span{ &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(2 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(8 * time.Millisecond), }, }, @@ -1498,13 +1498,13 @@ func TestScalarFilterEvaluate(t *testing.T) { // sum duration = 10ms &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(2 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(8 * time.Millisecond), }, }, @@ -1513,13 +1513,13 @@ func TestScalarFilterEvaluate(t *testing.T) { // sum duration = 27ms &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(12 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(15 * time.Millisecond), }, }, @@ -1531,13 +1531,13 @@ func TestScalarFilterEvaluate(t *testing.T) { Spans: []Span{ &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(2 * time.Millisecond), }, }, &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("a"), + NewAttribute("foo", false): NewStaticString("a"), NewIntrinsic(IntrinsicDuration): NewStaticDuration(8 * time.Millisecond), }, }, @@ -1558,205 +1558,205 @@ func TestBinaryOperationsWorkAcrossNumberTypes(t *testing.T) { { "{ .foo > 0 }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, }, { "{ .foo < 2 }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, }, { "{ .foo = 1 }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, }, { "{ .foo > 0. }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, }, { "{ .foo < 2. }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, }, { "{ .foo = 1. }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, }, { "{ .foo > 0ns }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, }, { "{ .foo < 2ns }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, }, { "{ .foo = 1ns }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticDuration(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{3}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticDuration(1)}}, }}}, }, // binops work with statics { "{ 1 > 0. }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, }}}, }, { "{ 0 < 2. }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, }}}, }, { "{ 1 = 1. }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, }}}, }, { "{ 1ms = 1ms }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, }}}, }, { "{ 1ns = 1 }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticFloat(1)}}, }}}, }, // binops work with attributes { "{ .foo < .bar }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(2)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(2), NewAttribute("bar"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(2)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(2), NewAttribute("bar", false): NewStaticFloat(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(2)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(2)}}, }}}, }, { "{ .bar > .foo }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(2)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(2), NewAttribute("bar"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(2)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(2), NewAttribute("bar", false): NewStaticFloat(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(2)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(2)}}, }}}, }, { "{ .foo = .bar }", []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}, - &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(2), NewAttribute("bar"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}, + &mockSpan{id: []byte{2}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(2), NewAttribute("bar", false): NewStaticFloat(1)}}, }}}, []*Spanset{{Spans: []Span{ - &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}, + &mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}, }}}, }, } @@ -1771,125 +1771,125 @@ func TestArithmetic(t *testing.T) { // static arithmetic works { "{ 1 + 1 = 2 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ 2 - 2 > -1 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ 1 / 10. = .1 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ 1 / 10 = 0 }", // integer division - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ 3 * 2 = 6 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ 10 % 3 = 1 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ 2 ^ 2 = 4 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ 2m + 2m = 4m }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ 2m * 2 = 4m }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, // attribute arithmetic works { "{ .foo + .bar = 2 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ .foo - 2 = -1 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ .foo / .bar != 3 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ .foo * .bar = 1 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ .foo % .bar = 0 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ .foo ^ .bar < 3 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, { "{ .foo * 3ms = 3ms }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1), NewAttribute("bar"): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1), NewAttribute("bar", false): NewStaticFloat(1)}}}}}, }, // complex true { "{ (2 - .bar) * .foo = -15}", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, }, { "{ 2 - .bar * .foo = -19}", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, }, { "{ 2 ^ (.bar * .foo) = 2097152}", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, }, { "{ .bar % 2 = .foo - 2 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, }, // complex false { "{ (2 - .bar) * .foo < -15}", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, []*Spanset{}, }, { "{ 2 - .bar * .foo > -19}", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, []*Spanset{}, }, { "{ 2 ^ (.bar * .foo) != 2097152}", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, []*Spanset{}, }, { "{ .bar % 2 < .foo - 2 }", - []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3), NewAttribute("bar"): NewStaticFloat(7)}}}}}, + []*Spanset{{Spans: []Span{&mockSpan{id: []byte{1}, attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3), NewAttribute("bar", false): NewStaticFloat(7)}}}}}, []*Spanset{}, }, } @@ -1910,7 +1910,7 @@ func TestSpansetExistence(t *testing.T) { query: `{ .foo != nil }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("bar"): NewStaticString("bzz"), + NewAttribute("bar", false): NewStaticString("bzz"), }, }, matches: false, @@ -1919,7 +1919,7 @@ func TestSpansetExistence(t *testing.T) { query: `{ .bar != nil }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("bar"): NewStaticString("bzz"), + NewAttribute("bar", false): NewStaticString("bzz"), }, }, matches: true, @@ -1928,7 +1928,7 @@ func TestSpansetExistence(t *testing.T) { query: `{ .int != nil }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("int"): NewStaticInt(1), + NewAttribute("int", false): NewStaticInt(1), }, }, matches: true, @@ -1937,7 +1937,7 @@ func TestSpansetExistence(t *testing.T) { query: `{ .duration != nil }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("duration"): NewStaticDuration(time.Minute), + NewAttribute("duration", false): NewStaticDuration(time.Minute), }, }, matches: true, @@ -1946,7 +1946,7 @@ func TestSpansetExistence(t *testing.T) { query: `{ .float != nil }`, span: &mockSpan{ attributes: map[Attribute]Static{ - NewAttribute("float"): NewStaticFloat(2.0), + NewAttribute("float", false): NewStaticFloat(2.0), }, }, matches: true, diff --git a/pkg/traceql/ast_test.go b/pkg/traceql/ast_test.go index 6e383a794cb..fe0885a04c9 100644 --- a/pkg/traceql/ast_test.go +++ b/pkg/traceql/ast_test.go @@ -575,8 +575,8 @@ func TestPipelineExtractConditions(t *testing.T) { "{ .foo1 = `a` } | { .foo2 = `b` }", FetchSpansRequest{ Conditions: []Condition{ - newCondition(NewAttribute("foo1"), OpEqual, NewStaticString("a")), - newCondition(NewAttribute("foo2"), OpEqual, NewStaticString("b")), + newCondition(NewAttribute("foo1", false), OpEqual, NewStaticString("a")), + newCondition(NewAttribute("foo2", false), OpEqual, NewStaticString("b")), }, AllConditions: false, }, @@ -585,8 +585,8 @@ func TestPipelineExtractConditions(t *testing.T) { "{ .foo = `a` } | by(.namespace) | count() > 3", FetchSpansRequest{ Conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("a")), - newCondition(NewAttribute("namespace"), OpNone), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("a")), + newCondition(NewAttribute("namespace", false), OpNone), }, AllConditions: false, }, @@ -595,7 +595,7 @@ func TestPipelineExtractConditions(t *testing.T) { "{ .foo = `a` } | avg(duration) > 20ms", FetchSpansRequest{ Conditions: []Condition{ - newCondition(NewAttribute("foo"), OpEqual, NewStaticString("a")), + newCondition(NewAttribute("foo", false), OpEqual, NewStaticString("a")), newCondition(NewIntrinsic(IntrinsicDuration), OpNone), }, AllConditions: false, @@ -643,13 +643,13 @@ func TestPipelineEvaluate(t *testing.T) { []*Spanset{ {Spans: []Span{ // First span should be dropped here - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo1"): NewStaticString("a")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo1"): NewStaticString("a"), NewAttribute("foo2"): NewStaticString("b")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo1", false): NewStaticString("a")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo1", false): NewStaticString("a"), NewAttribute("foo2", false): NewStaticString("b")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo1"): NewStaticString("a"), NewAttribute("foo2"): NewStaticString("b")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo1", false): NewStaticString("a"), NewAttribute("foo2", false): NewStaticString("b")}}, }}, }, }, @@ -688,17 +688,17 @@ func TestSpansetFilterEvaluate(t *testing.T) { []*Spanset{ {Spans: []Span{ // Second span should be dropped here - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, {Spans: []Span{ // This entire spanset will be dropped - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("b")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("b")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticString("a")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticString("a")}}, }}, }, }, @@ -707,21 +707,21 @@ func TestSpansetFilterEvaluate(t *testing.T) { []*Spanset{ {Spans: []Span{ // First span should be dropped here - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("200")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("201")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("300")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("301")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("200")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("201")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("300")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("301")}}, }}, {Spans: []Span{ // This entire spanset will be dropped - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("100")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("100")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("201")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("300")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("301")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("201")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("300")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("301")}}, }}, }, }, @@ -730,24 +730,24 @@ func TestSpansetFilterEvaluate(t *testing.T) { []*Spanset{ {Spans: []Span{ // Last span should be dropped here - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("200")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("201")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("300")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("301")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("200")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("201")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("300")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("301")}}, }}, {Spans: []Span{ // This entire spanset is valid - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("100")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("100")}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("200")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("201")}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("300")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("200")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("201")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("300")}}, }}, {Spans: []Span{ - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticString("100")}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticString("100")}}, }}, }, }, @@ -756,14 +756,14 @@ func TestSpansetFilterEvaluate(t *testing.T) { []*Spanset{ {Spans: []Span{ // This entire spanset will be dropped because mismatch type - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticInt(200)}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticInt(201)}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticInt(300)}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticInt(301)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticInt(200)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticInt(201)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticInt(300)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticInt(301)}}, }}, {Spans: []Span{ // This entire spanset will be dropped because mismatch type - &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status"): NewStaticInt(100)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("http.status", false): NewStaticInt(100)}}, }}, }, nil, @@ -773,28 +773,28 @@ func TestSpansetFilterEvaluate(t *testing.T) { []*Spanset{ {Spans: []Span{ // Second span should be dropped here - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(2)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(2)}}, }}, {Spans: []Span{ // First span should be dropped here - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(3)}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(4)}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(5)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(3)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(4)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(5)}}, }}, {Spans: []Span{ // Entire spanset should be dropped - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(6)}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(7)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(6)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(7)}}, }}, }, []*Spanset{ {Spans: []Span{ - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(1)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(1)}}, }}, {Spans: []Span{ - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(4)}}, - &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo"): NewStaticInt(5)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(4)}}, + &mockSpan{attributes: map[Attribute]Static{NewAttribute("foo", false): NewStaticInt(5)}}, }}, }, }, @@ -850,17 +850,17 @@ func (m *mockSpan) WithNestedSetInfo(parentid, left, right int) *mockSpan { } func (m *mockSpan) WithSpanString(key string, value string) *mockSpan { - m.attributes[NewScopedAttribute(AttributeScopeSpan, false, key)] = NewStaticString(value) + m.attributes[NewScopedAttribute(AttributeScopeSpan, false, key, false)] = NewStaticString(value) return m } func (m *mockSpan) WithSpanInt(key string, value int) *mockSpan { - m.attributes[NewScopedAttribute(AttributeScopeSpan, false, key)] = NewStaticInt(value) + m.attributes[NewScopedAttribute(AttributeScopeSpan, false, key, false)] = NewStaticInt(value) return m } func (m *mockSpan) WithAttrBool(key string, value bool) *mockSpan { - m.attributes[NewAttribute(key)] = NewStaticBool(value) + m.attributes[NewAttribute(key, false)] = NewStaticBool(value) return m } diff --git a/pkg/traceql/engine_metrics.go b/pkg/traceql/engine_metrics.go index 67adacf88d9..90507fa98dc 100644 --- a/pkg/traceql/engine_metrics.go +++ b/pkg/traceql/engine_metrics.go @@ -526,8 +526,8 @@ func NewGroupingAggregator(aggName string, innerAgg func() RangeAggregator, by [ // Unscoped attribute. Check span-level, then resource-level. // TODO - Is this taken care of by span.AttributeFor now? lookups[i] = []Attribute{ - NewScopedAttribute(AttributeScopeSpan, false, attr.Name), - NewScopedAttribute(AttributeScopeResource, false, attr.Name), + NewScopedAttribute(AttributeScopeSpan, false, attr.Name, false), + NewScopedAttribute(AttributeScopeResource, false, attr.Name, false), } } else { lookups[i] = []Attribute{attr} diff --git a/pkg/traceql/engine_metrics_test.go b/pkg/traceql/engine_metrics_test.go index fc52e276d69..d18d4a5f49d 100644 --- a/pkg/traceql/engine_metrics_test.go +++ b/pkg/traceql/engine_metrics_test.go @@ -272,7 +272,7 @@ func TestCompileMetricsQueryRangeFetchSpansRequest(t *testing.T) { SecondPassConditions: []Condition{ { // Group-by attributes (non-intrinsic) must be in the second pass - Attribute: NewScopedAttribute(AttributeScopeResource, false, "cluster"), + Attribute: NewScopedAttribute(AttributeScopeResource, false, "cluster", false), }, { // Since there is already a second pass then span start time isn't optimized to the first pass. @@ -297,7 +297,7 @@ func TestCompileMetricsQueryRangeFetchSpansRequest(t *testing.T) { }, { // Resource service name is treated as an intrinsic and moved to the first pass - Attribute: NewScopedAttribute(AttributeScopeResource, false, "service.name"), + Attribute: NewScopedAttribute(AttributeScopeResource, false, "service.name", false), }, { Attribute: IntrinsicSpanStartTimeAttribute, diff --git a/pkg/traceql/engine_test.go b/pkg/traceql/engine_test.go index 2721b87d409..b28fb47c6aa 100644 --- a/pkg/traceql/engine_test.go +++ b/pkg/traceql/engine_test.go @@ -46,7 +46,7 @@ func TestEngine_Execute(t *testing.T) { &mockSpan{ id: []byte{1}, attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("value"), + NewAttribute("foo", false): NewStaticString("value"), }, }, &mockSpan{ @@ -54,8 +54,8 @@ func TestEngine_Execute(t *testing.T) { startTimeUnixNanos: uint64(now.UnixNano()), durationNanos: uint64((100 * time.Millisecond).Nanoseconds()), attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("value"), - NewAttribute("bar"): NewStaticString("value"), + NewAttribute("foo", false): NewStaticString("value"), + NewAttribute("bar", false): NewStaticString("value"), }, }, &mockSpan{ @@ -63,8 +63,8 @@ func TestEngine_Execute(t *testing.T) { startTimeUnixNanos: uint64(now.UnixNano()), durationNanos: uint64((200 * time.Millisecond).Nanoseconds()), attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("value"), - NewAttribute("bar"): NewStaticString("value"), + NewAttribute("foo", false): NewStaticString("value"), + NewAttribute("bar", false): NewStaticString("value"), }, }, &mockSpan{ @@ -72,8 +72,8 @@ func TestEngine_Execute(t *testing.T) { startTimeUnixNanos: uint64(now.UnixNano()), durationNanos: uint64((100 * time.Millisecond).Nanoseconds()), attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("value"), - NewAttribute("bar"): NewStaticString("diff"), + NewAttribute("foo", false): NewStaticString("value"), + NewAttribute("bar", false): NewStaticString("diff"), }, }, &mockSpan{ @@ -81,8 +81,8 @@ func TestEngine_Execute(t *testing.T) { startTimeUnixNanos: uint64(now.UnixNano()), durationNanos: uint64((100 * time.Millisecond).Nanoseconds()), attributes: map[Attribute]Static{ - NewAttribute("foo"): NewStaticString("value"), - NewAttribute("bar"): NewStaticString("value"), + NewAttribute("foo", false): NewStaticString("value"), + NewAttribute("bar", false): NewStaticString("value"), }, }, }, @@ -95,7 +95,7 @@ func TestEngine_Execute(t *testing.T) { &mockSpan{ id: []byte{3}, attributes: map[Attribute]Static{ - NewAttribute("bar"): NewStaticString("value"), + NewAttribute("bar", false): NewStaticString("value"), }, }, }, @@ -109,8 +109,8 @@ func TestEngine_Execute(t *testing.T) { expectedFetchSpansRequest := FetchSpansRequest{ Conditions: []Condition{ - newCondition(NewAttribute("foo"), OpNone), - newCondition(NewAttribute("bar"), OpNone), + newCondition(NewAttribute("foo", false), OpNone), + newCondition(NewAttribute("bar", false), OpNone), }, AllConditions: true, SecondPassConditions: SearchMetaConditions(), @@ -230,14 +230,14 @@ func TestEngine_asTraceSearchMetadata(t *testing.T) { startTimeUnixNanos: uint64(now.UnixNano()), durationNanos: uint64((10 * time.Second).Nanoseconds()), attributes: map[Attribute]Static{ - NewIntrinsic(IntrinsicName): NewStaticString("HTTP GET"), - NewIntrinsic(IntrinsicStatus): NewStaticStatus(StatusOk), - NewIntrinsic(IntrinsicKind): NewStaticKind(KindClient), - NewAttribute("cluster"): NewStaticString("prod"), - NewAttribute("count"): NewStaticInt(5), - NewAttribute("count_but_float"): NewStaticFloat(5.0), - NewAttribute("is_ok"): NewStaticBool(true), - NewIntrinsic(IntrinsicDuration): NewStaticDuration(10 * time.Second), + NewIntrinsic(IntrinsicName): NewStaticString("HTTP GET"), + NewIntrinsic(IntrinsicStatus): NewStaticStatus(StatusOk), + NewIntrinsic(IntrinsicKind): NewStaticKind(KindClient), + NewAttribute("cluster", false): NewStaticString("prod"), + NewAttribute("count", false): NewStaticInt(5), + NewAttribute("count_but_float", false): NewStaticFloat(5.0), + NewAttribute("is_ok", false): NewStaticBool(true), + NewIntrinsic(IntrinsicDuration): NewStaticDuration(10 * time.Second), }, }, &mockSpan{ @@ -593,10 +593,10 @@ func TestExecuteTagValues(t *testing.T) { &mockSpan{ id: []byte{1}, attributes: map[Attribute]Static{ - NewIntrinsic(IntrinsicName): NewStaticString("HTTP POST /api/v1/users"), - NewScopedAttribute(AttributeScopeSpan, false, "http.method"): NewStaticString("POST"), - NewScopedAttribute(AttributeScopeSpan, false, "http.target"): NewStaticString("/api/v1/users"), - NewScopedAttribute(AttributeScopeResource, false, "service.name"): NewStaticString("my-service"), + NewIntrinsic(IntrinsicName): NewStaticString("HTTP POST /api/v1/users"), + NewScopedAttribute(AttributeScopeSpan, false, "http.method", false): NewStaticString("POST"), + NewScopedAttribute(AttributeScopeSpan, false, "http.target", false): NewStaticString("/api/v1/users"), + NewScopedAttribute(AttributeScopeResource, false, "service.name", false): NewStaticString("my-service"), }, }, &mockSpan{ @@ -604,8 +604,8 @@ func TestExecuteTagValues(t *testing.T) { startTimeUnixNanos: uint64(now.UnixNano()), durationNanos: uint64((100 * time.Millisecond).Nanoseconds()), attributes: map[Attribute]Static{ - NewIntrinsic(IntrinsicName): NewStaticString("redis call"), - NewScopedAttribute(AttributeScopeResource, false, "service.name"): NewStaticString("my-service"), + NewIntrinsic(IntrinsicName): NewStaticString("redis call"), + NewScopedAttribute(AttributeScopeResource, false, "service.name", false): NewStaticString("my-service"), }, }, }, @@ -618,10 +618,10 @@ func TestExecuteTagValues(t *testing.T) { &mockSpan{ id: []byte{3}, attributes: map[Attribute]Static{ - NewIntrinsic(IntrinsicName): NewStaticString("HTTP GET /status"), - NewScopedAttribute(AttributeScopeSpan, false, "http.method"): NewStaticString("GET"), - NewScopedAttribute(AttributeScopeSpan, false, "http.target"): NewStaticString("/status"), - NewScopedAttribute(AttributeScopeResource, false, "service.name"): NewStaticString("my-service"), + NewIntrinsic(IntrinsicName): NewStaticString("HTTP GET /status"), + NewScopedAttribute(AttributeScopeSpan, false, "http.method", false): NewStaticString("GET"), + NewScopedAttribute(AttributeScopeSpan, false, "http.target", false): NewStaticString("/status"), + NewScopedAttribute(AttributeScopeResource, false, "service.name", false): NewStaticString("my-service"), }, }, }, diff --git a/pkg/traceql/expr.y b/pkg/traceql/expr.y index 0524212e833..7a110d2b930 100644 --- a/pkg/traceql/expr.y +++ b/pkg/traceql/expr.y @@ -101,7 +101,7 @@ import ( BY COALESCE SELECT END_ATTRIBUTE RATE COUNT_OVER_TIME MIN_OVER_TIME QUANTILE_OVER_TIME HISTOGRAM_OVER_TIME COMPARE - WITH + WITH ARRAY // Operators are listed with increasing precedence. %left PIPE @@ -420,13 +420,22 @@ scopedIntrinsicField: ; attributeField: - DOT IDENTIFIER END_ATTRIBUTE { $$ = NewAttribute($2) } - | RESOURCE_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeResource, false, $2) } - | SPAN_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeSpan, false, $2) } - | PARENT_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeNone, true, $2) } - | PARENT_DOT RESOURCE_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeResource, true, $3) } - | PARENT_DOT SPAN_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeSpan, true, $3) } - | EVENT_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeEvent, false, $2) } - | LINK_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeLink, false, $2) } - | INSTRUMENTATION_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeInstrumentation, false, $2) } + DOT IDENTIFIER END_ATTRIBUTE { $$ = NewAttribute($2, false) } + | RESOURCE_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeResource, false, $2, false) } + | SPAN_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeSpan, false, $2, false) } + | PARENT_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeNone, true, $2, false) } + | PARENT_DOT RESOURCE_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeResource, true, $3, false) } + | PARENT_DOT SPAN_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeSpan, true, $3, false) } + | EVENT_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeEvent, false, $2, false) } + | LINK_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeLink, false, $2, false) } + | INSTRUMENTATION_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeInstrumentation, false, $2, false) } + | DOT IDENTIFIER ARRAY END_ATTRIBUTE { $$ = NewAttribute($2, true) } + | RESOURCE_DOT IDENTIFIER ARRAY END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeResource, false, $2, true) } + | SPAN_DOT IDENTIFIER ARRAY END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeSpan, false, $2, true) } + | PARENT_DOT IDENTIFIER ARRAY END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeNone, true, $2, true) } + | PARENT_DOT RESOURCE_DOT IDENTIFIER ARRAY END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeResource, true, $3, true) } + | PARENT_DOT SPAN_DOT IDENTIFIER ARRAY END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeSpan, true, $3, true) } + | EVENT_DOT IDENTIFIER ARRAY END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeEvent, false, $2, true) } + | LINK_DOT IDENTIFIER ARRAY END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeLink, false, $2, true) } + | INSTRUMENTATION_DOT IDENTIFIER ARRAY END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeInstrumentation, false, $2, true) } ; diff --git a/pkg/traceql/expr.y.go b/pkg/traceql/expr.y.go index 05bf701ce69..378bcf7c869 100644 --- a/pkg/traceql/expr.y.go +++ b/pkg/traceql/expr.y.go @@ -124,36 +124,37 @@ const QUANTILE_OVER_TIME = 57411 const HISTOGRAM_OVER_TIME = 57412 const COMPARE = 57413 const WITH = 57414 -const PIPE = 57415 -const AND = 57416 -const OR = 57417 -const EQ = 57418 -const NEQ = 57419 -const LT = 57420 -const LTE = 57421 -const GT = 57422 -const GTE = 57423 -const NRE = 57424 -const RE = 57425 -const DESC = 57426 -const ANCE = 57427 -const SIBL = 57428 -const NOT_CHILD = 57429 -const NOT_PARENT = 57430 -const NOT_DESC = 57431 -const NOT_ANCE = 57432 -const UNION_CHILD = 57433 -const UNION_PARENT = 57434 -const UNION_DESC = 57435 -const UNION_ANCE = 57436 -const UNION_SIBL = 57437 -const ADD = 57438 -const SUB = 57439 -const NOT = 57440 -const MUL = 57441 -const DIV = 57442 -const MOD = 57443 -const POW = 57444 +const ARRAY = 57415 +const PIPE = 57416 +const AND = 57417 +const OR = 57418 +const EQ = 57419 +const NEQ = 57420 +const LT = 57421 +const LTE = 57422 +const GT = 57423 +const GTE = 57424 +const NRE = 57425 +const RE = 57426 +const DESC = 57427 +const ANCE = 57428 +const SIBL = 57429 +const NOT_CHILD = 57430 +const NOT_PARENT = 57431 +const NOT_DESC = 57432 +const NOT_ANCE = 57433 +const UNION_CHILD = 57434 +const UNION_PARENT = 57435 +const UNION_DESC = 57436 +const UNION_ANCE = 57437 +const UNION_SIBL = 57438 +const ADD = 57439 +const SUB = 57440 +const NOT = 57441 +const MUL = 57442 +const DIV = 57443 +const MOD = 57444 +const POW = 57445 var yyToknames = [...]string{ "$end", @@ -228,6 +229,7 @@ var yyToknames = [...]string{ "HISTOGRAM_OVER_TIME", "COMPARE", "WITH", + "ARRAY", "PIPE", "AND", "OR", @@ -277,104 +279,107 @@ var yyExca = [...]int{ const yyPrivate = 57344 -const yyLast = 972 +const yyLast = 1002 var yyAct = [...]int{ 101, 6, 227, 5, 100, 8, 7, 98, 99, 283, 294, 2, 18, 67, 246, 228, 12, 13, 90, 77, - 66, 94, 334, 204, 30, 233, 234, 70, 235, 236, - 237, 246, 154, 29, 153, 203, 157, 155, 85, 86, - 203, 87, 88, 89, 90, 72, 73, 345, 74, 75, + 66, 94, 341, 204, 30, 233, 234, 70, 235, 236, + 237, 246, 154, 203, 153, 29, 157, 155, 85, 86, + 372, 87, 88, 89, 90, 72, 73, 371, 74, 75, 76, 77, 184, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 331, - 48, 53, 344, 327, 50, 376, 49, 326, 57, 210, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 338, + 48, 53, 361, 360, 50, 359, 49, 354, 57, 210, 51, 52, 54, 55, 56, 59, 58, 60, 61, 64, - 63, 62, 361, 231, 325, 342, 322, 230, 321, 320, - 204, 229, 218, 220, 221, 222, 223, 224, 225, 235, - 236, 237, 246, 226, 357, 319, 349, 249, 250, 251, - 348, 273, 274, 19, 20, 21, 382, 17, 351, 164, - 247, 248, 238, 239, 240, 241, 242, 243, 245, 244, - 238, 239, 240, 241, 242, 243, 245, 244, 87, 88, - 89, 90, 233, 234, 386, 235, 236, 237, 246, 255, - 233, 234, 330, 235, 236, 237, 246, 352, 291, 278, - 279, 280, 281, 350, 23, 26, 24, 25, 27, 14, - 165, 15, 292, 158, 159, 160, 161, 162, 163, 291, - 208, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 341, 256, 257, 385, 301, 154, 336, 153, 335, - 157, 155, 381, 301, 22, 85, 86, 296, 87, 88, - 89, 90, 298, 247, 248, 238, 239, 240, 241, 242, - 243, 245, 244, 261, 379, 301, 275, 292, 271, 17, - 262, 185, 263, 372, 301, 233, 234, 264, 235, 236, - 237, 246, 276, 272, 277, 302, 303, 304, 305, 306, + 63, 62, 357, 231, 349, 353, 208, 230, 352, 203, + 358, 229, 218, 220, 221, 222, 223, 224, 225, 235, + 236, 237, 246, 226, 351, 394, 379, 249, 250, 251, + 375, 238, 239, 240, 241, 242, 243, 245, 244, 232, + 365, 247, 248, 238, 239, 240, 241, 242, 243, 245, + 244, 233, 234, 364, 235, 236, 237, 246, 255, 404, + 275, 206, 271, 233, 234, 400, 235, 236, 237, 246, + 204, 337, 87, 88, 89, 90, 276, 272, 291, 278, + 279, 280, 281, 74, 75, 76, 77, 273, 274, 355, + 85, 86, 292, 87, 88, 89, 90, 356, 367, 291, + 368, 256, 257, 247, 248, 238, 239, 240, 241, 242, + 243, 245, 244, 366, 333, 331, 154, 348, 153, 343, + 157, 155, 334, 332, 342, 233, 234, 296, 235, 236, + 237, 246, 298, 247, 248, 238, 239, 240, 241, 242, + 243, 245, 244, 277, 329, 72, 73, 292, 74, 75, + 76, 77, 330, 207, 325, 233, 234, 398, 235, 236, + 237, 246, 326, 403, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 371, 301, 85, 86, 207, 87, 88, 89, 90, - 380, 265, 368, 266, 268, 269, 365, 267, 231, 231, - 231, 356, 230, 230, 230, 270, 229, 229, 229, 67, - 355, 67, 231, 337, 338, 339, 230, 340, 298, 293, - 229, 369, 370, 70, 290, 70, 289, 343, 31, 36, - 367, 366, 33, 288, 32, 287, 42, 286, 34, 35, - 37, 38, 39, 40, 41, 43, 44, 45, 46, 47, - 353, 354, 347, 346, 154, 285, 153, 211, 157, 155, - 332, 333, 300, 301, 167, 151, 231, 231, 363, 364, - 230, 230, 150, 149, 229, 229, 231, 148, 373, 231, - 230, 377, 147, 230, 229, 146, 92, 229, 91, 17, - 384, 231, 378, 383, 362, 230, 84, 375, 374, 229, - 102, 103, 104, 108, 131, 284, 93, 95, 71, 324, - 107, 105, 106, 110, 109, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 124, 123, 125, - 126, 323, 127, 128, 129, 130, 143, 144, 145, 360, - 359, 134, 132, 133, 138, 139, 140, 135, 141, 136, - 142, 137, 329, 102, 103, 104, 108, 131, 260, 259, - 95, 258, 254, 107, 105, 106, 110, 109, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 124, 123, 125, 126, 253, 127, 128, 129, 130, 328, - 68, 11, 96, 97, 134, 132, 133, 138, 139, 140, - 135, 141, 136, 142, 137, 78, 79, 80, 81, 82, - 83, 252, 28, 247, 248, 238, 239, 240, 241, 242, - 243, 245, 244, 318, 282, 72, 73, 358, 74, 75, - 76, 77, 69, 299, 16, 233, 234, 4, 235, 236, - 237, 246, 152, 10, 156, 96, 97, 1, 0, 0, + 317, 323, 17, 336, 19, 20, 21, 321, 17, 324, + 164, 386, 17, 319, 185, 322, 399, 301, 231, 231, + 231, 320, 230, 230, 230, 383, 229, 229, 229, 67, + 374, 67, 231, 344, 345, 346, 230, 347, 298, 261, + 229, 397, 301, 70, 373, 70, 262, 350, 263, 390, + 301, 389, 301, 264, 293, 23, 26, 24, 25, 27, + 14, 165, 15, 387, 388, 247, 248, 238, 239, 240, + 241, 242, 243, 245, 244, 385, 384, 369, 370, 363, + 362, 154, 402, 153, 290, 157, 155, 233, 234, 289, + 235, 236, 237, 246, 339, 340, 22, 265, 288, 266, + 268, 269, 287, 267, 231, 231, 381, 382, 230, 230, + 286, 270, 229, 229, 231, 285, 391, 231, 230, 395, + 211, 230, 229, 300, 301, 229, 167, 151, 150, 231, + 149, 401, 148, 230, 147, 146, 92, 229, 102, 103, + 104, 108, 131, 91, 93, 95, 393, 392, 107, 105, + 106, 110, 109, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 124, 123, 125, 126, 396, + 127, 128, 129, 130, 143, 144, 145, 378, 377, 134, + 132, 133, 138, 139, 140, 135, 141, 136, 142, 137, + 335, 380, 102, 103, 104, 108, 131, 284, 328, 95, + 327, 260, 107, 105, 106, 110, 109, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 124, + 123, 125, 126, 259, 127, 128, 129, 130, 318, 258, + 254, 96, 97, 134, 132, 133, 138, 139, 140, 135, + 141, 136, 142, 137, 78, 79, 80, 81, 82, 83, + 253, 84, 247, 248, 238, 239, 240, 241, 242, 243, + 245, 244, 299, 71, 85, 86, 252, 87, 88, 89, + 90, 28, 282, 376, 233, 234, 69, 235, 236, 237, + 246, 16, 4, 152, 10, 96, 97, 156, 1, 0, 247, 248, 238, 239, 240, 241, 242, 243, 245, 244, - 232, 0, 209, 212, 213, 214, 215, 216, 217, 0, - 208, 0, 233, 234, 0, 235, 236, 237, 246, 0, + 0, 0, 19, 20, 21, 0, 17, 0, 164, 0, + 0, 208, 233, 234, 0, 235, 236, 237, 246, 0, 0, 0, 0, 0, 247, 248, 238, 239, 240, 241, - 242, 243, 245, 244, 247, 248, 238, 239, 240, 241, - 242, 243, 245, 244, 205, 0, 233, 234, 0, 235, - 236, 237, 246, 0, 0, 0, 233, 234, 0, 235, - 236, 237, 246, 247, 248, 238, 239, 240, 241, 242, - 243, 245, 244, 78, 79, 80, 81, 82, 83, 202, - 0, 0, 0, 0, 0, 233, 234, 0, 235, 236, - 237, 246, 0, 85, 86, 0, 87, 88, 89, 90, - 0, 0, 0, 0, 0, 48, 53, 0, 0, 50, - 0, 49, 0, 57, 0, 51, 52, 54, 55, 56, - 59, 58, 60, 61, 64, 63, 62, 19, 20, 21, - 0, 17, 0, 164, 0, 0, 0, 0, 0, 0, - 31, 36, 0, 0, 33, 0, 32, 0, 42, 0, - 34, 35, 37, 38, 39, 40, 41, 43, 44, 45, - 46, 47, 206, 0, 0, 0, 0, 0, 19, 20, - 21, 0, 17, 0, 297, 0, 0, 0, 23, 26, - 24, 25, 27, 14, 165, 15, 19, 20, 21, 50, - 17, 49, 295, 57, 0, 51, 52, 54, 55, 56, - 59, 58, 60, 61, 64, 63, 62, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 22, 23, - 26, 24, 25, 27, 14, 0, 15, 19, 20, 21, - 0, 17, 0, 9, 0, 0, 0, 23, 26, 24, - 25, 27, 14, 0, 15, 72, 73, 0, 74, 75, - 76, 77, 0, 0, 33, 0, 32, 0, 42, 22, - 34, 35, 37, 38, 39, 40, 41, 43, 44, 45, - 46, 47, 0, 0, 0, 0, 0, 22, 23, 26, - 24, 25, 27, 14, 131, 15, 19, 20, 21, 0, - 17, 0, 164, 19, 20, 21, 0, 0, 0, 219, - 0, 0, 118, 119, 120, 121, 122, 124, 123, 125, - 126, 0, 127, 128, 129, 130, 0, 0, 22, 65, - 3, 134, 132, 133, 138, 139, 140, 135, 141, 136, - 142, 137, 0, 0, 0, 0, 0, 23, 26, 24, - 25, 27, 0, 0, 23, 26, 24, 25, 27, 0, - 0, 166, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 22, 102, 103, - 104, 108, 0, 0, 22, 211, 0, 0, 107, 105, + 242, 243, 245, 244, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 233, 234, 205, 235, + 236, 237, 246, 23, 26, 24, 25, 27, 14, 165, + 15, 0, 158, 159, 160, 161, 162, 163, 0, 0, + 202, 0, 0, 0, 0, 78, 79, 80, 81, 82, + 83, 0, 78, 79, 80, 81, 82, 83, 0, 0, + 0, 0, 0, 0, 22, 85, 86, 0, 87, 88, + 89, 90, 72, 73, 0, 74, 75, 76, 77, 0, + 48, 53, 0, 0, 50, 0, 49, 0, 57, 0, + 51, 52, 54, 55, 56, 59, 58, 60, 61, 64, + 63, 62, 31, 36, 0, 0, 33, 0, 32, 0, + 42, 0, 34, 35, 37, 38, 39, 40, 41, 43, + 44, 45, 46, 47, 31, 36, 0, 0, 33, 0, + 32, 0, 42, 0, 34, 35, 37, 38, 39, 40, + 41, 43, 44, 45, 46, 47, 19, 20, 21, 0, + 17, 0, 297, 0, 19, 20, 21, 50, 17, 49, + 295, 57, 0, 51, 52, 54, 55, 56, 59, 58, + 60, 61, 64, 63, 62, 33, 0, 32, 0, 42, + 0, 34, 35, 37, 38, 39, 40, 41, 43, 44, + 45, 46, 47, 0, 0, 0, 0, 23, 26, 24, + 25, 27, 14, 0, 15, 23, 26, 24, 25, 27, + 14, 0, 15, 19, 20, 21, 0, 17, 0, 9, + 0, 19, 20, 21, 0, 17, 0, 164, 19, 20, + 21, 0, 0, 0, 219, 0, 0, 0, 22, 0, + 0, 0, 0, 0, 0, 0, 22, 0, 0, 68, + 11, 0, 65, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 23, 26, 24, 25, 27, 14, + 0, 15, 23, 26, 24, 25, 27, 0, 0, 23, + 26, 24, 25, 27, 166, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 0, 0, 0, 0, 22, 0, 0, 0, 0, + 131, 0, 0, 22, 0, 0, 0, 0, 0, 0, + 22, 209, 212, 213, 214, 215, 216, 217, 118, 119, + 120, 121, 122, 124, 123, 125, 126, 0, 127, 128, + 129, 130, 0, 0, 0, 0, 0, 134, 132, 133, + 138, 139, 140, 135, 141, 136, 142, 137, 102, 103, + 104, 108, 0, 0, 0, 211, 0, 0, 107, 105, 106, 110, 109, 111, 112, 113, 114, 115, 116, 117, 102, 103, 104, 108, 0, 0, 0, 0, 0, 0, 107, 105, 106, 110, 109, 111, 112, 113, 114, 115, @@ -382,51 +387,53 @@ var yyAct = [...]int{ } var yyPact = [...]int{ - 771, -39, -49, 244, -1000, -4, -1000, -1000, -1000, 771, - -1000, 419, -1000, 119, 366, 364, -1000, 385, -1000, -1000, - -1000, -1000, 420, 363, 360, 355, 351, 350, -1000, 343, - 117, 342, 342, 342, 342, 342, 342, 342, 342, 342, - 342, 342, 342, 342, 342, 342, 342, 342, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 616, 27, 581, 699, 262, - 547, 923, 335, 335, 335, 335, 335, 335, -1000, -1000, - -1000, -1000, -1000, -1000, 837, 837, 837, 837, 837, 837, - 837, 438, 825, -1000, 539, 438, 438, 438, -1000, -1000, + 807, -37, -50, 649, -1000, -5, -1000, -1000, -1000, 807, + -1000, 575, -1000, 437, 401, 394, -1000, 403, -1000, -1000, + -1000, -1000, 438, 393, 392, 390, 388, 386, -1000, 385, + 566, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 384, 384, 384, 384, 384, 384, 384, 384, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 627, 86, 605, 138, 230, + 568, 953, 378, 378, 378, 378, 378, 378, -1000, -1000, + -1000, -1000, -1000, -1000, 822, 822, 822, 822, 822, 822, + 822, 457, 901, -1000, 118, 457, 457, 457, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 497, 470, 448, 155, 447, 445, 444, 206, 254, - 209, 79, 207, -1000, -1000, -1000, 241, 438, 438, 438, - 438, 391, -1000, -4, -1000, -1000, -1000, -1000, 333, 315, - 313, 311, 304, 302, 830, 297, 726, 730, -1000, -1000, - -1000, -1000, 726, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 661, 229, -1000, -1000, -1000, -1000, - 661, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 671, -1000, -1000, -1000, -1000, -51, - -1000, 712, 92, 92, -83, -83, -83, -83, -58, 837, - 49, 49, -84, -84, -84, -84, 510, 339, -1000, -1000, - -1000, -1000, -1000, 438, 438, 438, 438, 438, 438, 438, - 438, 438, 438, 438, 438, 438, 438, 438, 438, 500, - 10, 10, 50, 34, 33, 31, 417, 395, 29, 12, - 8, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 466, 429, - 149, 56, 337, -1000, -54, 196, 194, 825, 825, 825, - 369, 581, 177, 188, 22, 730, -1000, 712, -50, -1000, - -1000, 825, 10, 10, -88, -88, -88, -71, -71, -71, - -71, -71, -71, -71, -71, -88, 64, 64, -1000, -1000, - -1000, -1000, -1000, 7, -18, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 391, 945, 58, 54, 160, 114, 154, - 327, -1000, 671, -1000, -1000, -1000, -1000, -1000, 288, 279, - 52, 423, 30, -1000, 378, 825, 825, 274, 307, -1000, - -1000, 270, 298, 258, 230, 825, 381, 13, 825, -1000, - 376, -1000, -1000, 221, -1000, -1000, 268, 199, 112, -1000, - 825, -1000, 374, 191, 141, -1000, -1000, + -1000, 532, 516, 496, 144, 495, 489, 467, 282, 340, + 123, 135, 121, -1000, -1000, -1000, 220, 457, 457, 457, + 457, 463, -1000, -5, -1000, -1000, -1000, -1000, 373, 368, + 360, 356, 347, 342, 815, 312, 696, 748, -1000, -1000, + -1000, -1000, 696, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 678, 272, -1000, -1000, -1000, -1000, + 678, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 268, -1000, -1000, -1000, -1000, -52, + -1000, 740, 73, 73, -84, -84, -84, -84, -59, 822, + 62, 62, -85, -85, -85, -85, 519, 380, -1000, -1000, + -1000, -1000, -1000, 457, 457, 457, 457, 457, 457, 457, + 457, 457, 457, 457, 457, 457, 457, 457, 457, 485, + 9, 9, 218, 212, 206, 179, 466, 464, 169, 140, + 139, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 447, 260, + 148, 56, 351, -1000, -55, 201, 196, 901, 901, 901, + 262, 605, 83, 194, 20, 748, -1000, 740, -51, -1000, + -1000, 901, 9, 9, -89, -89, -89, -72, -72, -72, + -72, -72, -72, -72, -72, -89, 44, 44, -1000, -1000, + 49, -1000, 33, -1000, 30, -1000, 12, 114, 27, -1000, + 10, -1000, 8, -1000, 7, -1000, -1000, -1000, -1000, -1000, + 463, 975, 81, 68, 190, 174, 177, 334, -1000, 268, + -1000, -1000, -1000, -1000, -1000, -1000, -18, -1000, -25, -1000, + -1000, -1000, -1000, -1000, 302, 288, 58, 441, 54, -1000, + 455, -1000, -1000, 901, 901, 283, 332, -1000, -1000, 269, + 320, 308, 306, 901, 410, 53, 901, -1000, 433, -1000, + -1000, 298, -1000, -1000, 235, 273, 141, -1000, 901, -1000, + 346, 240, 136, -1000, -1000, } var yyPgo = [...]int{ - 0, 537, 6, 534, 5, 2, 3, 869, 533, 10, - 16, 1, 386, 532, 527, 480, 17, 524, 522, 12, - 21, 7, 8, 4, 0, 15, 517, 9, 514, 502, + 0, 558, 6, 557, 5, 2, 3, 852, 554, 10, + 16, 1, 521, 553, 552, 849, 17, 551, 546, 12, + 21, 7, 8, 4, 0, 15, 543, 9, 542, 541, } var yyR1 = [...]int{ @@ -450,6 +457,7 @@ var yyR1 = [...]int{ 22, 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, } var yyR2 = [...]int{ @@ -473,19 +481,20 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 4, 4, 4, } var yyChk = [...]int{ -1000, -1, -9, -7, -14, -6, -11, -2, -4, 12, -8, -15, -10, -16, 62, 64, -17, 10, -19, 6, - 7, 8, 97, 57, 59, 60, 58, 61, -29, 72, - 73, 74, 80, 78, 84, 85, 75, 86, 87, 88, - 89, 90, 82, 91, 92, 93, 94, 95, 74, 80, - 78, 84, 85, 75, 86, 87, 88, 82, 90, 89, - 91, 92, 95, 94, 93, -7, -9, -6, -15, -18, - -16, -12, 96, 97, 99, 100, 101, 102, 76, 77, - 78, 79, 80, 81, -12, 96, 97, 99, 100, 101, - 102, 12, 12, 11, -20, 12, 97, 98, -21, -22, + 7, 8, 98, 57, 59, 60, 58, 61, -29, 72, + 74, 75, 81, 79, 85, 86, 76, 87, 88, 89, + 90, 91, 83, 92, 93, 94, 95, 96, 75, 81, + 79, 85, 86, 76, 87, 88, 89, 83, 91, 90, + 92, 93, 96, 95, 94, -7, -9, -6, -15, -18, + -16, -12, 97, 98, 100, 101, 102, 103, 77, 78, + 79, 80, 81, 82, -12, 97, 98, 100, 101, 102, + 103, 12, 12, 11, -20, 12, 98, 99, -21, -22, -23, -24, 5, 6, 7, 16, 17, 15, 8, 19, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 32, 34, 35, 37, 38, 39, @@ -496,11 +505,11 @@ var yyChk = [...]int{ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -6, 12, -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, - -6, -6, 13, 13, 73, 13, 13, 13, 13, -15, + -6, -6, 13, 13, 74, 13, 13, 13, 13, -15, -21, 12, -15, -15, -15, -15, -15, -15, -16, 12, -16, -16, -16, -16, -16, -16, -20, -5, -25, -22, - -23, -24, 11, 96, 97, 99, 100, 101, 76, 77, - 78, 79, 80, 81, 83, 82, 102, 74, 75, -20, + -23, -24, 11, 97, 98, 100, 101, 102, 77, 78, + 79, 80, 81, 82, 84, 83, 103, 75, 76, -20, -20, -20, 4, 4, 4, 4, 47, 48, 4, 4, 4, 27, 34, 36, 41, 27, 29, 33, 30, 31, 41, 29, 44, 42, 43, 29, 45, 13, -20, -20, @@ -508,13 +517,15 @@ var yyChk = [...]int{ 12, -6, -16, 12, -9, 12, -19, 12, -9, 13, 13, 14, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, 13, 65, - 65, 65, 65, 4, 4, 65, 65, 65, 13, 13, - 13, 13, 13, 14, 76, 13, 13, -25, -25, -25, - -10, 13, 73, -25, 65, 65, -27, -21, 62, 62, - 13, 14, 13, 13, 14, 12, 12, 62, -26, 7, - 6, 62, 6, -5, -5, 12, 14, 13, 12, 13, - 14, 13, 13, -5, 7, 6, 62, -5, 6, 13, - 12, 13, 14, -5, 6, 13, 13, + 73, 65, 73, 65, 73, 65, 73, 4, 4, 65, + 73, 65, 73, 65, 73, 13, 13, 13, 13, 13, + 14, 77, 13, 13, -25, -25, -25, -10, 13, 74, + -25, 65, 65, 65, 65, 65, 73, 65, 73, 65, + 65, 65, -27, -21, 62, 62, 13, 14, 13, 13, + 14, 65, 65, 12, 12, 62, -26, 7, 6, 62, + 6, -5, -5, 12, 14, 13, 12, 13, 14, 13, + 13, -5, 7, 6, 62, -5, 6, 13, 12, 13, + 14, -5, 6, 13, 13, } var yyDef = [...]int{ @@ -550,13 +561,15 @@ var yyDef = [...]int{ 0, 0, 0, 0, 0, 0, -2, 0, 0, 35, 37, 0, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 123, 191, - 192, 193, 194, 0, 0, 197, 198, 199, 102, 103, - 104, 105, 120, 0, 0, 106, 108, 0, 0, 0, - 0, 36, 0, 42, 195, 196, 122, 119, 0, 0, - 110, 0, 114, 116, 0, 0, 0, 0, 0, 43, - 44, 0, 0, 0, 0, 0, 0, 112, 0, 117, - 0, 107, 109, 0, 45, 46, 0, 0, 0, 111, - 0, 115, 0, 0, 0, 113, 118, + 0, 192, 0, 193, 0, 194, 0, 0, 0, 197, + 0, 198, 0, 199, 0, 102, 103, 104, 105, 120, + 0, 0, 106, 108, 0, 0, 0, 0, 36, 0, + 42, 200, 201, 202, 203, 195, 0, 196, 0, 206, + 207, 208, 122, 119, 0, 0, 110, 0, 114, 116, + 0, 204, 205, 0, 0, 0, 0, 43, 44, 0, + 0, 0, 0, 0, 0, 112, 0, 117, 0, 107, + 109, 0, 45, 46, 0, 0, 0, 111, 0, 115, + 0, 0, 0, 113, 118, } var yyTok1 = [...]int{ @@ -574,7 +587,7 @@ var yyTok2 = [...]int{ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, + 102, 103, } var yyTok3 = [...]int{ 0, @@ -2061,55 +2074,109 @@ yydefault: yyDollar = yyS[yypt-3 : yypt+1] //line pkg/traceql/expr.y:423 { - yyVAL.attributeField = NewAttribute(yyDollar[2].staticStr) + yyVAL.attributeField = NewAttribute(yyDollar[2].staticStr, false) } case 192: yyDollar = yyS[yypt-3 : yypt+1] //line pkg/traceql/expr.y:424 { - yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, false, yyDollar[2].staticStr) + yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, false, yyDollar[2].staticStr, false) } case 193: yyDollar = yyS[yypt-3 : yypt+1] //line pkg/traceql/expr.y:425 { - yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, false, yyDollar[2].staticStr) + yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, false, yyDollar[2].staticStr, false) } case 194: yyDollar = yyS[yypt-3 : yypt+1] //line pkg/traceql/expr.y:426 { - yyVAL.attributeField = NewScopedAttribute(AttributeScopeNone, true, yyDollar[2].staticStr) + yyVAL.attributeField = NewScopedAttribute(AttributeScopeNone, true, yyDollar[2].staticStr, false) } case 195: yyDollar = yyS[yypt-4 : yypt+1] //line pkg/traceql/expr.y:427 { - yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, true, yyDollar[3].staticStr) + yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, true, yyDollar[3].staticStr, false) } case 196: yyDollar = yyS[yypt-4 : yypt+1] //line pkg/traceql/expr.y:428 { - yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, true, yyDollar[3].staticStr) + yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, true, yyDollar[3].staticStr, false) } case 197: yyDollar = yyS[yypt-3 : yypt+1] //line pkg/traceql/expr.y:429 { - yyVAL.attributeField = NewScopedAttribute(AttributeScopeEvent, false, yyDollar[2].staticStr) + yyVAL.attributeField = NewScopedAttribute(AttributeScopeEvent, false, yyDollar[2].staticStr, false) } case 198: yyDollar = yyS[yypt-3 : yypt+1] //line pkg/traceql/expr.y:430 { - yyVAL.attributeField = NewScopedAttribute(AttributeScopeLink, false, yyDollar[2].staticStr) + yyVAL.attributeField = NewScopedAttribute(AttributeScopeLink, false, yyDollar[2].staticStr, false) } case 199: yyDollar = yyS[yypt-3 : yypt+1] //line pkg/traceql/expr.y:431 { - yyVAL.attributeField = NewScopedAttribute(AttributeScopeInstrumentation, false, yyDollar[2].staticStr) + yyVAL.attributeField = NewScopedAttribute(AttributeScopeInstrumentation, false, yyDollar[2].staticStr, false) + } + case 200: + yyDollar = yyS[yypt-4 : yypt+1] +//line pkg/traceql/expr.y:432 + { + yyVAL.attributeField = NewAttribute(yyDollar[2].staticStr, true) + } + case 201: + yyDollar = yyS[yypt-4 : yypt+1] +//line pkg/traceql/expr.y:433 + { + yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, false, yyDollar[2].staticStr, true) + } + case 202: + yyDollar = yyS[yypt-4 : yypt+1] +//line pkg/traceql/expr.y:434 + { + yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, false, yyDollar[2].staticStr, true) + } + case 203: + yyDollar = yyS[yypt-4 : yypt+1] +//line pkg/traceql/expr.y:435 + { + yyVAL.attributeField = NewScopedAttribute(AttributeScopeNone, true, yyDollar[2].staticStr, true) + } + case 204: + yyDollar = yyS[yypt-5 : yypt+1] +//line pkg/traceql/expr.y:436 + { + yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, true, yyDollar[3].staticStr, true) + } + case 205: + yyDollar = yyS[yypt-5 : yypt+1] +//line pkg/traceql/expr.y:437 + { + yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, true, yyDollar[3].staticStr, true) + } + case 206: + yyDollar = yyS[yypt-4 : yypt+1] +//line pkg/traceql/expr.y:438 + { + yyVAL.attributeField = NewScopedAttribute(AttributeScopeEvent, false, yyDollar[2].staticStr, true) + } + case 207: + yyDollar = yyS[yypt-4 : yypt+1] +//line pkg/traceql/expr.y:439 + { + yyVAL.attributeField = NewScopedAttribute(AttributeScopeLink, false, yyDollar[2].staticStr, true) + } + case 208: + yyDollar = yyS[yypt-4 : yypt+1] +//line pkg/traceql/expr.y:440 + { + yyVAL.attributeField = NewScopedAttribute(AttributeScopeInstrumentation, false, yyDollar[2].staticStr, true) } } goto yystack /* stack new state and value */ diff --git a/pkg/traceql/lexer.go b/pkg/traceql/lexer.go index af13f13abc8..abbfde44a23 100644 --- a/pkg/traceql/lexer.go +++ b/pkg/traceql/lexer.go @@ -107,6 +107,7 @@ var tokens = map[string]int{ "histogram_over_time": HISTOGRAM_OVER_TIME, "compare": COMPARE, "with": WITH, + "[]": ARRAY, } type lexer struct { @@ -124,6 +125,10 @@ func (l *lexer) Lex(lval *yySymType) int { // this attribute will end, then return a special token indicating that the attribute is // done parsing if l.parsingAttribute && !isAttributeRune(l.Peek()) { + // check if the attribute ends with [], and return ARRAY token before we return END_ATTRIBUTE + if l.checkArrayEnd() { + return ARRAY + } l.parsingAttribute = false return END_ATTRIBUTE } @@ -147,6 +152,7 @@ func (l *lexer) Lex(lval *yySymType) int { r := l.Scan() // now that we know we're not parsing an attribute, let's look for everything else + // we should find and return the Array token here switch r { case scanner.EOF: return 0 @@ -201,6 +207,9 @@ func (l *lexer) Lex(lval *yySymType) int { // look for combination tokens starting with 2 and working up til there is no match // this is only to disamgiguate tokens with common prefixes. it will not find 3+ token combinations // with no valid prefixes + // FIXME: this can also be used to parse and return the ARRAY token at the end of the attribute?? + // multiTok does fund ARRAY token but I think we need to advance the scanner to consume the [] tokens + // and then return ARRAY token, and mark it as end of attribute??? multiTok := -1 tokStrNext := l.TokenText() for { @@ -403,7 +412,7 @@ func isAttributeRune(r rune) bool { } switch r { - case scanner.EOF, '{', '}', '(', ')', '=', '~', '!', '<', '>', '&', '|', '^', ',': + case scanner.EOF, '{', '}', '(', ')', '=', '~', '!', '<', '>', '&', '|', '^', ',', '[', ']': return false default: return true @@ -419,3 +428,14 @@ func startsAttribute(tok int) bool { tok == LINK_DOT || tok == INSTRUMENTATION_DOT } + +func (l *lexer) checkArrayEnd() bool { + if l.Peek() == '[' { + l.Next() // consume '[' + if l.Peek() == ']' { + l.Next() // consume ']' + return true + } + } + return false +} diff --git a/pkg/traceql/lexer_test.go b/pkg/traceql/lexer_test.go index 42aec121f05..d890a88c47b 100644 --- a/pkg/traceql/lexer_test.go +++ b/pkg/traceql/lexer_test.go @@ -15,7 +15,7 @@ type lexerTestCase struct { } func TestLexerAttributes(t *testing.T) { - testLexer(t, ([]lexerTestCase{ + testLexer(t, []lexerTestCase{ // attributes {`.foo`, []int{DOT, IDENTIFIER, END_ATTRIBUTE}}, {`."foo".baz."bar"`, []int{DOT, IDENTIFIER, END_ATTRIBUTE}}, @@ -76,7 +76,7 @@ func TestLexerAttributes(t *testing.T) { {`parent.resource.foo3`, []int{PARENT_DOT, RESOURCE_DOT, IDENTIFIER, END_ATTRIBUTE}}, {`parent.resource.foo+bar`, []int{PARENT_DOT, RESOURCE_DOT, IDENTIFIER, END_ATTRIBUTE}}, {`parent.resource.foo-bar`, []int{PARENT_DOT, RESOURCE_DOT, IDENTIFIER, END_ATTRIBUTE}}, - // attribute enders: , {, }, (, ), all force end an attribute + // attribute enders: , {, }, (, ), [,] all force end an attribute {`.foo .bar`, []int{DOT, IDENTIFIER, END_ATTRIBUTE, DOT, IDENTIFIER, END_ATTRIBUTE}}, {`.foo}.bar`, []int{DOT, IDENTIFIER, END_ATTRIBUTE, CLOSE_BRACE, DOT, IDENTIFIER, END_ATTRIBUTE}}, {`.foo{.bar`, []int{DOT, IDENTIFIER, END_ATTRIBUTE, OPEN_BRACE, DOT, IDENTIFIER, END_ATTRIBUTE}}, @@ -84,14 +84,80 @@ func TestLexerAttributes(t *testing.T) { {`.foo(.bar`, []int{DOT, IDENTIFIER, END_ATTRIBUTE, OPEN_PARENS, DOT, IDENTIFIER, END_ATTRIBUTE}}, {`.foo,.bar`, []int{DOT, IDENTIFIER, END_ATTRIBUTE, COMMA, DOT, IDENTIFIER, END_ATTRIBUTE}}, {`. foo`, []int{DOT, END_ATTRIBUTE, IDENTIFIER}}, + {`.[foo`, []int{DOT, END_ATTRIBUTE, IDENTIFIER}}, + // FIXME: dig and fix this test?? + // {`.]foo`, []int{DOT, END_ATTRIBUTE, IDENTIFIER}}, // not attributes {`.3`, []int{FLOAT}}, {`.24h`, []int{DURATION}}, - })) + }) +} + +func TestLexerAttributesArray(t *testing.T) { + testLexer(t, []lexerTestCase{ + // attributes with array + {`.foo[]`, []int{DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`."foo".baz."bar"[]`, []int{DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`.foo."bar \" baz"."bar"[]`, []int{DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`.foo."baz \\".bar[]`, []int{DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`."foo.bar"[]`, []int{DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`.count[]`, []int{DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`.foo3[]`, []int{DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`.foo+bar[]`, []int{DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`.foo-bar[]`, []int{DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + // parent attributes with array + {`parent.foo[]`, []int{PARENT_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.count[]`, []int{PARENT_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.foo3[]`, []int{PARENT_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.foo+bar[]`, []int{PARENT_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.foo-bar[]`, []int{PARENT_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + // span attributes with array + {`span.foo[]`, []int{SPAN_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`span.count[]`, []int{SPAN_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`span.foo3[]`, []int{SPAN_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`span.foo+bar[]`, []int{SPAN_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`span.foo-bar[]`, []int{SPAN_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + // resource attributes with array + {`resource.foo[]`, []int{RESOURCE_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`resource.count[]`, []int{RESOURCE_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`resource.foo3[]`, []int{RESOURCE_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`resource.foo+bar[]`, []int{RESOURCE_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`resource.foo-bar[]`, []int{RESOURCE_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + // event attributes with array + {`event.foo[]`, []int{EVENT_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`event.count[]`, []int{EVENT_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`event.foo3[]`, []int{EVENT_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`event.foo+bar[]`, []int{EVENT_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`event.foo-bar[]`, []int{EVENT_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + // link attributes with array + {`link.foo[]`, []int{LINK_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`link.count[]`, []int{LINK_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`link.foo3[]`, []int{LINK_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`link.foo+bar[]`, []int{LINK_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`link.foo-bar[]`, []int{LINK_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + // instrumentation attributes with array + {`instrumentation.foo[]`, []int{INSTRUMENTATION_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`instrumentation.count[]`, []int{INSTRUMENTATION_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`instrumentation.foo3[]`, []int{INSTRUMENTATION_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`instrumentation.foo+bar[]`, []int{INSTRUMENTATION_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`instrumentation.foo-bar[]`, []int{INSTRUMENTATION_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + // parent span attributes with array + {`parent.span.foo[]`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.span.count[]`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.span.foo3[]`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.span.foo+bar[]`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.span.foo-bar[]`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + // parent resource attributes with array + {`parent.resource.foo[]`, []int{PARENT_DOT, RESOURCE_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.resource.count[]`, []int{PARENT_DOT, RESOURCE_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.resource.foo3[]`, []int{PARENT_DOT, RESOURCE_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.resource.foo+bar[]`, []int{PARENT_DOT, RESOURCE_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + {`parent.resource.foo-bar[]`, []int{PARENT_DOT, RESOURCE_DOT, IDENTIFIER, ARRAY, END_ATTRIBUTE}}, + }) } func TestLexerScopedIntrinsic(t *testing.T) { - testLexer(t, ([]lexerTestCase{ + testLexer(t, []lexerTestCase{ // trace scoped intrinsics {`trace:duration`, []int{TRACE_COLON, IDURATION}}, {`trace:rootName`, []int{TRACE_COLON, ROOTNAME}}, @@ -113,19 +179,19 @@ func TestLexerScopedIntrinsic(t *testing.T) { // instrumentation scoped intrinsics {`instrumentation:name`, []int{INSTRUMENTATION_COLON, NAME}}, {`instrumentation:version`, []int{INSTRUMENTATION_COLON, VERSION}}, - })) + }) } func TestLexerIntrinsics(t *testing.T) { - testLexer(t, ([]lexerTestCase{ + testLexer(t, []lexerTestCase{ {`nestedSetLeft`, []int{NESTEDSETLEFT}}, {`nestedSetRight`, []int{NESTEDSETRIGHT}}, {`duration`, []int{IDURATION}}, - })) + }) } func TestLexerMultitokens(t *testing.T) { - testLexer(t, ([]lexerTestCase{ + testLexer(t, []lexerTestCase{ // attributes {`&&`, []int{AND}}, {`>>`, []int{DESC}}, @@ -133,11 +199,12 @@ func TestLexerMultitokens(t *testing.T) { {`!`, []int{NOT}}, {`!~`, []int{NRE}}, {`&>>`, []int{UNION_DESC}}, - })) + {`[]`, []int{ARRAY}}, // TODO: should this be here?? no idea? figure it out? + }) } func TestLexerDuration(t *testing.T) { - testLexer(t, ([]lexerTestCase{ + testLexer(t, []lexerTestCase{ // duration {"1ns", []int{DURATION}}, {"1s", []int{DURATION}}, @@ -152,7 +219,7 @@ func TestLexerDuration(t *testing.T) { // not duration {"1t", []int{INTEGER, IDENTIFIER}}, {"1", []int{INTEGER}}, - })) + }) } func TestLexerParseDuration(t *testing.T) { @@ -184,7 +251,7 @@ func TestLexerParseDuration(t *testing.T) { } func TestLexerScoping(t *testing.T) { - testLexer(t, ([]lexerTestCase{ + testLexer(t, []lexerTestCase{ {`span.foo3`, []int{SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}}, {`span.foo+bar`, []int{SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}}, {`span.foo-bar`, []int{SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}}, @@ -202,7 +269,7 @@ func TestLexerScoping(t *testing.T) { {`parent.span.foo`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}}, {`parent.span.count`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}}, {`parent.span.resource.id`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}}, - })) + }) } func testLexer(t *testing.T, tcs []lexerTestCase) { diff --git a/pkg/traceql/parse.go b/pkg/traceql/parse.go index dce74318ae1..8ac0353376c 100644 --- a/pkg/traceql/parse.go +++ b/pkg/traceql/parse.go @@ -55,17 +55,17 @@ func ParseIdentifier(s string) (Attribute, error) { switch { case strings.HasPrefix(s, "."): - return NewAttribute(strings.TrimPrefix(s, ".")), nil + return NewAttribute(strings.TrimPrefix(s, "."), false), nil case strings.HasPrefix(s, "resource."): - return NewScopedAttribute(AttributeScopeResource, false, strings.TrimPrefix(s, "resource.")), nil + return NewScopedAttribute(AttributeScopeResource, false, strings.TrimPrefix(s, "resource."), false), nil case strings.HasPrefix(s, "span."): - return NewScopedAttribute(AttributeScopeSpan, false, strings.TrimPrefix(s, "span.")), nil + return NewScopedAttribute(AttributeScopeSpan, false, strings.TrimPrefix(s, "span."), false), nil case strings.HasPrefix(s, "instrumentation."): - return NewScopedAttribute(AttributeScopeInstrumentation, false, strings.TrimPrefix(s, "instrumentation.")), nil + return NewScopedAttribute(AttributeScopeInstrumentation, false, strings.TrimPrefix(s, "instrumentation."), false), nil case strings.HasPrefix(s, "event."): - return NewScopedAttribute(AttributeScopeEvent, false, strings.TrimPrefix(s, "event.")), nil + return NewScopedAttribute(AttributeScopeEvent, false, strings.TrimPrefix(s, "event."), false), nil case strings.HasPrefix(s, "link."): - return NewScopedAttribute(AttributeScopeLink, false, strings.TrimPrefix(s, "link.")), nil + return NewScopedAttribute(AttributeScopeLink, false, strings.TrimPrefix(s, "link."), false), nil default: return Attribute{}, fmt.Errorf("tag name is not valid intrinsic or scoped attribute: %s", s) } diff --git a/pkg/traceql/parse_test.go b/pkg/traceql/parse_test.go index 779c53436c7..6cc1caa63f3 100644 --- a/pkg/traceql/parse_test.go +++ b/pkg/traceql/parse_test.go @@ -40,17 +40,17 @@ func TestPipelineOperatorPrecedence(t *testing.T) { expected: newSpansetOperation(OpSpansetAnd, newSpansetOperation(OpSpansetChild, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -58,17 +58,17 @@ func TestPipelineOperatorPrecedence(t *testing.T) { in: "({ .a } | { .b }) > (({ .a } | { .b }) && ({ .a } | { .b }))", expected: newSpansetOperation(OpSpansetChild, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newSpansetOperation(OpSpansetAnd, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), ), @@ -77,17 +77,17 @@ func TestPipelineOperatorPrecedence(t *testing.T) { in: "({ .a } | { .b }) < (({ .a } | { .b }) && ({ .a } | { .b }))", expected: newSpansetOperation(OpSpansetParent, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newSpansetOperation(OpSpansetAnd, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), ), @@ -113,12 +113,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) > ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetChild, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -126,12 +126,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) < ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetParent, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -139,12 +139,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) ~ ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetSibling, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -152,12 +152,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) && ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetAnd, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -165,12 +165,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) >> ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetDescendant, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -178,12 +178,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) << ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetAncestor, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -191,12 +191,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) !> ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetNotChild, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -204,12 +204,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) !< ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetNotParent, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -217,12 +217,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) !~ ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetNotSibling, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -230,12 +230,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) !>> ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetNotDescendant, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -243,12 +243,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) !<< ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetNotAncestor, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -256,12 +256,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) &> ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetUnionChild, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -269,12 +269,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) &< ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetUnionParent, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -282,12 +282,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) &~ ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetUnionSibling, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -295,12 +295,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) &>> ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetUnionDescendant, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -308,12 +308,12 @@ func TestPipelineSpansetOperators(t *testing.T) { in: "({ .a } | { .b }) &<< ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetUnionAncestor, newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), ), }, @@ -338,11 +338,11 @@ func TestPipelineScalarOperators(t *testing.T) { in: "({ .a } | count()) = ({ .a } | count())", expected: newScalarFilter(OpEqual, newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newAggregate(aggregateCount, nil), ), newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newAggregate(aggregateCount, nil), ), ), @@ -351,11 +351,11 @@ func TestPipelineScalarOperators(t *testing.T) { in: "({ .a } | count()) != ({ .a } | count())", expected: newScalarFilter(OpNotEqual, newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newAggregate(aggregateCount, nil), ), newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newAggregate(aggregateCount, nil), ), ), @@ -364,11 +364,11 @@ func TestPipelineScalarOperators(t *testing.T) { in: "({ .a } | count()) < ({ .a } | count())", expected: newScalarFilter(OpLess, newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newAggregate(aggregateCount, nil), ), newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newAggregate(aggregateCount, nil), ), ), @@ -377,11 +377,11 @@ func TestPipelineScalarOperators(t *testing.T) { in: "({ .a } | count()) <= ({ .a } | count())", expected: newScalarFilter(OpLessEqual, newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newAggregate(aggregateCount, nil), ), newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newAggregate(aggregateCount, nil), ), ), @@ -390,11 +390,11 @@ func TestPipelineScalarOperators(t *testing.T) { in: "({ .a } | count()) >= ({ .a } | count())", expected: newScalarFilter(OpGreaterEqual, newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newAggregate(aggregateCount, nil), ), newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newAggregate(aggregateCount, nil), ), ), @@ -419,22 +419,22 @@ func TestPipelines(t *testing.T) { { in: "{ .a } | { .b }", expected: newPipeline( - newSpansetFilter(NewAttribute("a")), - newSpansetFilter(NewAttribute("b")), + newSpansetFilter(NewAttribute("a", false)), + newSpansetFilter(NewAttribute("b", false)), ), }, { in: "{ .a } | count() > 1", expected: newPipeline( - newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("a", false)), newScalarFilter(OpGreater, newAggregate(aggregateCount, nil), NewStaticInt(1)), ), }, { in: "{ .a } | by(.namespace) | coalesce() | avg(duration) = 1s ", expected: newPipeline( - newSpansetFilter(NewAttribute("a")), - newGroupOperation(NewAttribute("namespace")), + newSpansetFilter(NewAttribute("a", false)), + newGroupOperation(NewAttribute("namespace", false)), newCoalesceOperation(), newScalarFilter(OpEqual, newAggregate(aggregateAvg, NewIntrinsic(IntrinsicDuration)), NewStaticDuration(time.Second)), ), @@ -475,8 +475,8 @@ func TestGroupCoalesceOperation(t *testing.T) { in string expected Pipeline }{ - {in: "by(.a) | coalesce()", expected: newPipeline(newGroupOperation(NewAttribute("a")), newCoalesceOperation())}, - {in: "by(.a + .b)", expected: newPipeline(newGroupOperation(newBinaryOperation(OpAdd, NewAttribute("a"), NewAttribute("b"))))}, + {in: "by(.a) | coalesce()", expected: newPipeline(newGroupOperation(NewAttribute("a", false)), newCoalesceOperation())}, + {in: "by(.a + .b)", expected: newPipeline(newGroupOperation(newBinaryOperation(OpAdd, NewAttribute("a", false), NewAttribute("b", false))))}, } for _, tc := range tests { @@ -512,8 +512,8 @@ func TestSelectOperation(t *testing.T) { in string expected Pipeline }{ - {in: "select(.a)", expected: newPipeline(newSelectOperation([]Attribute{NewAttribute("a")}))}, - {in: "select(.a,.b)", expected: newPipeline(newSelectOperation([]Attribute{NewAttribute("a"), NewAttribute("b")}))}, + {in: "select(.a)", expected: newPipeline(newSelectOperation([]Attribute{NewAttribute("a", false)}))}, + {in: "select(.a,.b)", expected: newPipeline(newSelectOperation([]Attribute{NewAttribute("a", false), NewAttribute("b", false)}))}, } for _, tc := range tests { @@ -659,10 +659,10 @@ func TestScalarExpressionPrecedence(t *testing.T) { { in: "avg(.foo) > count() + sum(.bar)", expected: newScalarFilter(OpGreater, - newAggregate(aggregateAvg, NewAttribute("foo")), + newAggregate(aggregateAvg, NewAttribute("foo", false)), newScalarOperation(OpAdd, newAggregate(aggregateCount, nil), - newAggregate(aggregateSum, NewAttribute("bar")), + newAggregate(aggregateSum, NewAttribute("bar", false)), ), ), }, @@ -670,10 +670,10 @@ func TestScalarExpressionPrecedence(t *testing.T) { in: "avg(.foo) + count() > sum(.bar)", expected: newScalarFilter(OpGreater, newScalarOperation(OpAdd, - newAggregate(aggregateAvg, NewAttribute("foo")), + newAggregate(aggregateAvg, NewAttribute("foo", false)), newAggregate(aggregateCount, nil), ), - newAggregate(aggregateSum, NewAttribute("bar")), + newAggregate(aggregateSum, NewAttribute("bar", false)), ), }, } @@ -694,7 +694,7 @@ func TestScalarExpressionOperators(t *testing.T) { expected ScalarFilter }{ {in: "count() > 1", expected: newScalarFilter(OpGreater, newAggregate(aggregateCount, nil), NewStaticInt(1))}, - {in: "max(.a) > 1", expected: newScalarFilter(OpGreater, newAggregate(aggregateMax, NewAttribute("a")), NewStaticInt(1))}, + {in: "max(.a) > 1", expected: newScalarFilter(OpGreater, newAggregate(aggregateMax, NewAttribute("a", false)), NewStaticInt(1))}, {in: "min(1) > 1", expected: newScalarFilter(OpGreater, newAggregate(aggregateMin, NewStaticInt(1)), NewStaticInt(1))}, {in: "sum(true) > 1", expected: newScalarFilter(OpGreater, newAggregate(aggregateSum, NewStaticBool(true)), NewStaticInt(1))}, {in: "avg(`c`) > 1", expected: newScalarFilter(OpGreater, newAggregate(aggregateAvg, NewStaticString("c")), NewStaticInt(1))}, @@ -738,104 +738,104 @@ func TestSpansetFilterOperatorPrecedence(t *testing.T) { { in: "{ .a * .b + .c }", expected: newBinaryOperation(OpAdd, - newBinaryOperation(OpMult, NewAttribute("a"), NewAttribute("b")), - NewAttribute("c")), + newBinaryOperation(OpMult, NewAttribute("a", false), NewAttribute("b", false)), + NewAttribute("c", false)), }, { in: "{ .a + .b * .c }", expected: newBinaryOperation(OpAdd, - NewAttribute("a"), - newBinaryOperation(OpMult, NewAttribute("b"), NewAttribute("c"))), + NewAttribute("a", false), + newBinaryOperation(OpMult, NewAttribute("b", false), NewAttribute("c", false))), }, { in: "{ ( .a + .b ) * .c }", expected: newBinaryOperation(OpMult, - newBinaryOperation(OpAdd, NewAttribute("a"), NewAttribute("b")), - NewAttribute("c")), + newBinaryOperation(OpAdd, NewAttribute("a", false), NewAttribute("b", false)), + NewAttribute("c", false)), }, { in: "{ .a + .b ^ .c }", expected: newBinaryOperation(OpAdd, - NewAttribute("a"), - newBinaryOperation(OpPower, NewAttribute("b"), NewAttribute("c"))), + NewAttribute("a", false), + newBinaryOperation(OpPower, NewAttribute("b", false), NewAttribute("c", false))), }, { in: "{ .a = .b + .c }", expected: newBinaryOperation(OpEqual, - NewAttribute("a"), - newBinaryOperation(OpAdd, NewAttribute("b"), NewAttribute("c"))), + NewAttribute("a", false), + newBinaryOperation(OpAdd, NewAttribute("b", false), NewAttribute("c", false))), }, { in: "{ .a + .b = .c }", expected: newBinaryOperation(OpEqual, - newBinaryOperation(OpAdd, NewAttribute("a"), NewAttribute("b")), - NewAttribute("c")), + newBinaryOperation(OpAdd, NewAttribute("a", false), NewAttribute("b", false)), + NewAttribute("c", false)), }, { in: "{ .c - -.a + .b }", expected: newBinaryOperation(OpAdd, - newBinaryOperation(OpSub, NewAttribute("c"), newUnaryOperation(OpSub, NewAttribute("a"))), - NewAttribute("b")), + newBinaryOperation(OpSub, NewAttribute("c", false), newUnaryOperation(OpSub, NewAttribute("a", false))), + NewAttribute("b", false)), }, { in: "{ .c - -( .a + .b ) }", expected: newBinaryOperation(OpSub, - NewAttribute("c"), - newUnaryOperation(OpSub, newBinaryOperation(OpAdd, NewAttribute("a"), NewAttribute("b")))), + NewAttribute("c", false), + newUnaryOperation(OpSub, newBinaryOperation(OpAdd, NewAttribute("a", false), NewAttribute("b", false)))), }, { in: "{ .a && .b = .c }", expected: newBinaryOperation(OpAnd, - NewAttribute("a"), - newBinaryOperation(OpEqual, NewAttribute("b"), NewAttribute("c"))), + NewAttribute("a", false), + newBinaryOperation(OpEqual, NewAttribute("b", false), NewAttribute("c", false))), }, { in: "{ .a = .b && .c }", expected: newBinaryOperation(OpAnd, - newBinaryOperation(OpEqual, NewAttribute("a"), NewAttribute("b")), - NewAttribute("c")), + newBinaryOperation(OpEqual, NewAttribute("a", false), NewAttribute("b", false)), + NewAttribute("c", false)), }, { in: "{ .a = !.b && .c }", expected: newBinaryOperation(OpAnd, - newBinaryOperation(OpEqual, NewAttribute("a"), newUnaryOperation(OpNot, NewAttribute("b"))), - NewAttribute("c")), + newBinaryOperation(OpEqual, NewAttribute("a", false), newUnaryOperation(OpNot, NewAttribute("b", false))), + NewAttribute("c", false)), }, { in: "{ .a = !( .b && .c ) }", expected: newBinaryOperation(OpEqual, - NewAttribute("a"), - newUnaryOperation(OpNot, newBinaryOperation(OpAnd, NewAttribute("b"), NewAttribute("c")))), + NewAttribute("a", false), + newUnaryOperation(OpNot, newBinaryOperation(OpAnd, NewAttribute("b", false), NewAttribute("c", false)))), }, { in: "{ .a = .b || .c = .d}", expected: newBinaryOperation(OpOr, - newBinaryOperation(OpEqual, NewAttribute("a"), NewAttribute("b")), - newBinaryOperation(OpEqual, NewAttribute("c"), NewAttribute("d"))), + newBinaryOperation(OpEqual, NewAttribute("a", false), NewAttribute("b", false)), + newBinaryOperation(OpEqual, NewAttribute("c", false), NewAttribute("d", false))), }, { in: "{ !.a = .b }", expected: newBinaryOperation(OpEqual, - newUnaryOperation(OpNot, NewAttribute("a")), - NewAttribute("b")), + newUnaryOperation(OpNot, NewAttribute("a", false)), + NewAttribute("b", false)), }, { in: "{ !(.a = .b) }", expected: newUnaryOperation(OpNot, newBinaryOperation(OpEqual, - NewAttribute("a"), - NewAttribute("b"))), + NewAttribute("a", false), + NewAttribute("b", false))), }, { in: "{ -.a = .b }", expected: newBinaryOperation(OpEqual, - newUnaryOperation(OpSub, NewAttribute("a")), - NewAttribute("b")), + newUnaryOperation(OpSub, NewAttribute("a", false)), + NewAttribute("b", false)), }, { in: "{ -(.a = .b) }", expected: newUnaryOperation(OpSub, newBinaryOperation(OpEqual, - NewAttribute("a"), - NewAttribute("b"))), + NewAttribute("a", false), + NewAttribute("b", false))), }, } @@ -859,7 +859,7 @@ func TestSpansetFilterStatics(t *testing.T) { {in: `{ "true" }`, expected: NewStaticString("true")}, {in: `{ "true\"" }`, expected: NewStaticString("true\"")}, {in: "{ `foo` }", expected: NewStaticString("foo")}, - {in: "{ .foo }", expected: NewAttribute("foo")}, + {in: "{ .foo }", expected: NewAttribute("foo", false)}, {in: "{ duration }", expected: NewIntrinsic(IntrinsicDuration)}, {in: "{ childCount }", expected: NewIntrinsic(IntrinsicChildCount)}, {in: "{ name }", expected: NewIntrinsic(IntrinsicName)}, @@ -898,34 +898,34 @@ func TestSpansetFilterOperators(t *testing.T) { expected FieldExpression alsoTestWithoutSpace bool }{ - {in: "{ .a + .b }", expected: newBinaryOperation(OpAdd, NewAttribute("a"), NewAttribute("b"))}, - {in: "{ .a - .b }", expected: newBinaryOperation(OpSub, NewAttribute("a"), NewAttribute("b"))}, - {in: "{ .a / .b }", expected: newBinaryOperation(OpDiv, NewAttribute("a"), NewAttribute("b"))}, - {in: "{ .a % .b }", expected: newBinaryOperation(OpMod, NewAttribute("a"), NewAttribute("b"))}, - {in: "{ .a * .b }", expected: newBinaryOperation(OpMult, NewAttribute("a"), NewAttribute("b"))}, - {in: "{ .a = .b }", expected: newBinaryOperation(OpEqual, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ .a != .b }", expected: newBinaryOperation(OpNotEqual, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ .a =~ .b }", expected: newBinaryOperation(OpRegex, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ .a !~ .b }", expected: newBinaryOperation(OpNotRegex, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ .a > .b }", expected: newBinaryOperation(OpGreater, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ .a >= .b }", expected: newBinaryOperation(OpGreaterEqual, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ .a < .b }", expected: newBinaryOperation(OpLess, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ .a <= .b }", expected: newBinaryOperation(OpLessEqual, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ .a ^ .b }", expected: newBinaryOperation(OpPower, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ .a && .b }", expected: newBinaryOperation(OpAnd, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ .a || .b }", expected: newBinaryOperation(OpOr, NewAttribute("a"), NewAttribute("b")), alsoTestWithoutSpace: true}, - {in: "{ !.b }", expected: newUnaryOperation(OpNot, NewAttribute("b"))}, - {in: "{ -.b }", expected: newUnaryOperation(OpSub, NewAttribute("b"))}, + {in: "{ .a + .b }", expected: newBinaryOperation(OpAdd, NewAttribute("a", false), NewAttribute("b", false))}, + {in: "{ .a - .b }", expected: newBinaryOperation(OpSub, NewAttribute("a", false), NewAttribute("b", false))}, + {in: "{ .a / .b }", expected: newBinaryOperation(OpDiv, NewAttribute("a", false), NewAttribute("b", false))}, + {in: "{ .a % .b }", expected: newBinaryOperation(OpMod, NewAttribute("a", false), NewAttribute("b", false))}, + {in: "{ .a * .b }", expected: newBinaryOperation(OpMult, NewAttribute("a", false), NewAttribute("b", false))}, + {in: "{ .a = .b }", expected: newBinaryOperation(OpEqual, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ .a != .b }", expected: newBinaryOperation(OpNotEqual, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ .a =~ .b }", expected: newBinaryOperation(OpRegex, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ .a !~ .b }", expected: newBinaryOperation(OpNotRegex, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ .a > .b }", expected: newBinaryOperation(OpGreater, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ .a >= .b }", expected: newBinaryOperation(OpGreaterEqual, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ .a < .b }", expected: newBinaryOperation(OpLess, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ .a <= .b }", expected: newBinaryOperation(OpLessEqual, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ .a ^ .b }", expected: newBinaryOperation(OpPower, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ .a && .b }", expected: newBinaryOperation(OpAnd, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ .a || .b }", expected: newBinaryOperation(OpOr, NewAttribute("a", false), NewAttribute("b", false)), alsoTestWithoutSpace: true}, + {in: "{ !.b }", expected: newUnaryOperation(OpNot, NewAttribute("b", false))}, + {in: "{ -.b }", expected: newUnaryOperation(OpSub, NewAttribute("b", false))}, // Against statics - {in: "{ .a = `foo` }", expected: newBinaryOperation(OpEqual, NewAttribute("a"), NewStaticString("foo")), alsoTestWithoutSpace: true}, - {in: "{ .a = 3 }", expected: newBinaryOperation(OpEqual, NewAttribute("a"), NewStaticInt(3)), alsoTestWithoutSpace: true}, - {in: "{ .a = 3.0 }", expected: newBinaryOperation(OpEqual, NewAttribute("a"), NewStaticFloat(3)), alsoTestWithoutSpace: true}, - {in: "{ .a = true }", expected: newBinaryOperation(OpEqual, NewAttribute("a"), NewStaticBool(true)), alsoTestWithoutSpace: true}, + {in: "{ .a = `foo` }", expected: newBinaryOperation(OpEqual, NewAttribute("a", false), NewStaticString("foo")), alsoTestWithoutSpace: true}, + {in: "{ .a = 3 }", expected: newBinaryOperation(OpEqual, NewAttribute("a", false), NewStaticInt(3)), alsoTestWithoutSpace: true}, + {in: "{ .a = 3.0 }", expected: newBinaryOperation(OpEqual, NewAttribute("a", false), NewStaticFloat(3)), alsoTestWithoutSpace: true}, + {in: "{ .a = true }", expected: newBinaryOperation(OpEqual, NewAttribute("a", false), NewStaticBool(true)), alsoTestWithoutSpace: true}, // existence - {in: "{ .a != nil }", expected: newBinaryOperation(OpNotEqual, NewAttribute("a"), NewStaticNil()), alsoTestWithoutSpace: true}, - {in: "{ .a = nil }", expected: newBinaryOperation(OpEqual, NewAttribute("a"), NewStaticNil()), alsoTestWithoutSpace: true}, + {in: "{ .a != nil }", expected: newBinaryOperation(OpNotEqual, NewAttribute("a", false), NewStaticNil()), alsoTestWithoutSpace: true}, + {in: "{ .a = nil }", expected: newBinaryOperation(OpEqual, NewAttribute("a", false), NewStaticNil()), alsoTestWithoutSpace: true}, } test := func(q string, expected FieldExpression) { @@ -980,7 +980,7 @@ func TestBinaryAndUnaryOperationsCollapseToStatics(t *testing.T) { {in: "{ 1 = 1. }", expected: NewStaticBool(true)}, // this is an interesting case, it returns true even though { span.foo = 1 } would be false if span.foo had the float value 1.0 {in: "{ .1 + 1 }", expected: NewStaticFloat(1.1)}, {in: "{ 1 * -1 = -1 }", expected: NewStaticBool(true)}, - {in: "{ .foo * -1. = -1 }", expected: newBinaryOperation(OpEqual, newBinaryOperation(OpMult, NewAttribute("foo"), NewStaticFloat(-1)), NewStaticInt(-1))}, + {in: "{ .foo * -1. = -1 }", expected: newBinaryOperation(OpEqual, newBinaryOperation(OpMult, NewAttribute("foo", false), NewStaticFloat(-1)), NewStaticInt(-1))}, } test := func(t *testing.T, q string, expected FieldExpression) { @@ -1003,42 +1003,93 @@ func TestAttributes(t *testing.T) { }{ {in: "duration", expected: NewIntrinsic(IntrinsicDuration)}, {in: "kind", expected: NewIntrinsic(IntrinsicKind)}, - {in: ".foo", expected: NewAttribute("foo")}, - {in: ".max", expected: NewAttribute("max")}, - {in: ".status", expected: NewAttribute("status")}, - {in: ".kind", expected: NewAttribute("kind")}, - {in: ".foo.bar", expected: NewAttribute("foo.bar")}, - {in: ".foo.bar.baz", expected: NewAttribute("foo.bar.baz")}, - {in: ".foo.3", expected: NewAttribute("foo.3")}, - {in: ".foo3", expected: NewAttribute("foo3")}, - {in: ".http_status", expected: NewAttribute("http_status")}, - {in: ".http-status", expected: NewAttribute("http-status")}, - {in: ".http+", expected: NewAttribute("http+")}, - {in: ".😝", expected: NewAttribute("😝")}, - {in: ".http-other", expected: NewAttribute("http-other")}, - {in: "parent.duration", expected: NewScopedAttribute(AttributeScopeNone, true, "duration")}, - {in: "parent.foo.bar.baz", expected: NewScopedAttribute(AttributeScopeNone, true, "foo.bar.baz")}, - {in: "resource.foo.bar.baz", expected: NewScopedAttribute(AttributeScopeResource, false, "foo.bar.baz")}, - {in: "span.foo.bar", expected: NewScopedAttribute(AttributeScopeSpan, false, "foo.bar")}, - {in: "event.foo.bar", expected: NewScopedAttribute(AttributeScopeEvent, false, "foo.bar")}, - {in: "link.foo.bar", expected: NewScopedAttribute(AttributeScopeLink, false, "foo.bar")}, - {in: "instrumentation.foo.bar", expected: NewScopedAttribute(AttributeScopeInstrumentation, false, "foo.bar")}, - {in: "parent.resource.foo", expected: NewScopedAttribute(AttributeScopeResource, true, "foo")}, - {in: "parent.span.foo", expected: NewScopedAttribute(AttributeScopeSpan, true, "foo")}, - {in: "parent.resource.foo.bar.baz", expected: NewScopedAttribute(AttributeScopeResource, true, "foo.bar.baz")}, - {in: "parent.span.foo.bar", expected: NewScopedAttribute(AttributeScopeSpan, true, "foo.bar")}, - {in: `."bar z".foo`, expected: NewAttribute("bar z.foo")}, - {in: `span."bar z".foo`, expected: NewScopedAttribute(AttributeScopeSpan, false, "bar z.foo")}, - {in: `."bar z".foo."bar"`, expected: NewAttribute("bar z.foo.bar")}, - {in: `.foo."bar baz"`, expected: NewAttribute("foo.bar baz")}, - {in: `.foo."bar baz".bar`, expected: NewAttribute("foo.bar baz.bar")}, - {in: `.foo."bar \" baz"`, expected: NewAttribute(`foo.bar " baz`)}, - {in: `.foo."bar \\ baz"`, expected: NewAttribute(`foo.bar \ baz`)}, - {in: `.foo."bar \\"." baz"`, expected: NewAttribute(`foo.bar \. baz`)}, - {in: `."foo.bar"`, expected: NewAttribute(`foo.bar`)}, - {in: `."🤘"`, expected: NewAttribute(`🤘`)}, + {in: ".foo", expected: NewAttribute("foo", false)}, + {in: ".max", expected: NewAttribute("max", false)}, + {in: ".status", expected: NewAttribute("status", false)}, + {in: ".kind", expected: NewAttribute("kind", false)}, + {in: ".foo.bar", expected: NewAttribute("foo.bar", false)}, + {in: ".foo.bar.baz", expected: NewAttribute("foo.bar.baz", false)}, + {in: ".foo.3", expected: NewAttribute("foo.3", false)}, + {in: ".foo3", expected: NewAttribute("foo3", false)}, + {in: ".http_status", expected: NewAttribute("http_status", false)}, + {in: ".http-status", expected: NewAttribute("http-status", false)}, + {in: ".http+", expected: NewAttribute("http+", false)}, + {in: ".😝", expected: NewAttribute("😝", false)}, + {in: ".http-other", expected: NewAttribute("http-other", false)}, + {in: "parent.duration", expected: NewScopedAttribute(AttributeScopeNone, true, "duration", false)}, + {in: "parent.foo.bar.baz", expected: NewScopedAttribute(AttributeScopeNone, true, "foo.bar.baz", false)}, + {in: "resource.foo.bar.baz", expected: NewScopedAttribute(AttributeScopeResource, false, "foo.bar.baz", false)}, + {in: "span.foo.bar", expected: NewScopedAttribute(AttributeScopeSpan, false, "foo.bar", false)}, + {in: "event.foo.bar", expected: NewScopedAttribute(AttributeScopeEvent, false, "foo.bar", false)}, + {in: "link.foo.bar", expected: NewScopedAttribute(AttributeScopeLink, false, "foo.bar", false)}, + {in: "instrumentation.foo.bar", expected: NewScopedAttribute(AttributeScopeInstrumentation, false, "foo.bar", false)}, + {in: "parent.resource.foo", expected: NewScopedAttribute(AttributeScopeResource, true, "foo", false)}, + {in: "parent.span.foo", expected: NewScopedAttribute(AttributeScopeSpan, true, "foo", false)}, + {in: "parent.resource.foo.bar.baz", expected: NewScopedAttribute(AttributeScopeResource, true, "foo.bar.baz", false)}, + {in: "parent.span.foo.bar", expected: NewScopedAttribute(AttributeScopeSpan, true, "foo.bar", false)}, + {in: `."bar z".foo`, expected: NewAttribute("bar z.foo", false)}, + {in: `span."bar z".foo`, expected: NewScopedAttribute(AttributeScopeSpan, false, "bar z.foo", false)}, + {in: `."bar z".foo."bar"`, expected: NewAttribute("bar z.foo.bar", false)}, + {in: `.foo."bar baz"`, expected: NewAttribute("foo.bar baz", false)}, + {in: `.foo."bar baz".bar`, expected: NewAttribute("foo.bar baz.bar", false)}, + {in: `.foo."bar \" baz"`, expected: NewAttribute(`foo.bar " baz`, false)}, + {in: `.foo."bar \\ baz"`, expected: NewAttribute(`foo.bar \ baz`, false)}, + {in: `.foo."bar \\"." baz"`, expected: NewAttribute(`foo.bar \. baz`, false)}, + {in: `."foo.bar"`, expected: NewAttribute(`foo.bar`, false)}, + {in: `."🤘"`, expected: NewAttribute(`🤘`, false)}, } + runAttributeTests(t, tests) +} + +func TestArrayAttributes(t *testing.T) { + tests := []struct { + in string + expected FieldExpression + }{ + {in: ".foo[]", expected: NewAttribute("foo", true)}, + {in: ".max[]", expected: NewAttribute("max", true)}, + {in: ".status[]", expected: NewAttribute("status", true)}, + {in: ".kind[]", expected: NewAttribute("kind", true)}, + {in: ".foo.bar[]", expected: NewAttribute("foo.bar", true)}, + {in: ".foo.bar.baz[]", expected: NewAttribute("foo.bar.baz", true)}, + {in: ".foo.3[]", expected: NewAttribute("foo.3", true)}, + {in: ".foo3[]", expected: NewAttribute("foo3", true)}, + {in: ".http_status[]", expected: NewAttribute("http_status", true)}, + {in: ".http-status[]", expected: NewAttribute("http-status", true)}, + {in: ".http+[]", expected: NewAttribute("http+", true)}, + {in: ".😝[]", expected: NewAttribute("😝", true)}, + {in: ".http-other[]", expected: NewAttribute("http-other", true)}, + {in: "parent.duration[]", expected: NewScopedAttribute(AttributeScopeNone, true, "duration", true)}, + {in: "parent.foo.bar.baz[]", expected: NewScopedAttribute(AttributeScopeNone, true, "foo.bar.baz", true)}, + {in: "resource.foo.bar.baz[]", expected: NewScopedAttribute(AttributeScopeResource, false, "foo.bar.baz", true)}, + {in: "span.foo.bar[]", expected: NewScopedAttribute(AttributeScopeSpan, false, "foo.bar", true)}, + {in: "event.foo.bar[]", expected: NewScopedAttribute(AttributeScopeEvent, false, "foo.bar", true)}, + {in: "link.foo.bar[]", expected: NewScopedAttribute(AttributeScopeLink, false, "foo.bar", true)}, + {in: "instrumentation.foo.bar[]", expected: NewScopedAttribute(AttributeScopeInstrumentation, false, "foo.bar", true)}, + {in: "parent.resource.foo[]", expected: NewScopedAttribute(AttributeScopeResource, true, "foo", true)}, + {in: "parent.span.foo[]", expected: NewScopedAttribute(AttributeScopeSpan, true, "foo", true)}, + {in: "parent.resource.foo.bar.baz[]", expected: NewScopedAttribute(AttributeScopeResource, true, "foo.bar.baz", true)}, + {in: "parent.span.foo.bar[]", expected: NewScopedAttribute(AttributeScopeSpan, true, "foo.bar", true)}, + {in: `."bar z".foo[]`, expected: NewAttribute("bar z.foo", true)}, + {in: `span."bar z".foo[]`, expected: NewScopedAttribute(AttributeScopeSpan, false, "bar z.foo", true)}, + {in: `."bar z".foo."bar"[]`, expected: NewAttribute("bar z.foo.bar", true)}, + {in: `.foo."bar baz"[]`, expected: NewAttribute("foo.bar baz", true)}, + {in: `.foo."bar baz".bar[]`, expected: NewAttribute("foo.bar baz.bar", true)}, + {in: `.foo."bar \" baz"[]`, expected: NewAttribute(`foo.bar " baz`, true)}, + {in: `.foo."bar \\ baz"[]`, expected: NewAttribute(`foo.bar \ baz`, true)}, + {in: `.foo."bar \\"." baz"[]`, expected: NewAttribute(`foo.bar \. baz`, true)}, + {in: `."foo.bar"[]`, expected: NewAttribute(`foo.bar`, true)}, + {in: `."🤘"[]`, expected: NewAttribute(`🤘`, true)}, + } + + runAttributeTests(t, tests) +} + +func runAttributeTests(t *testing.T, tests []struct { + in string + expected FieldExpression +}) { for _, tc := range tests { t.Run(tc.in, func(t *testing.T) { s := "{ " + tc.in + " }" @@ -1256,11 +1307,11 @@ func TestParseIdentifier(t *testing.T) { "status": NewIntrinsic(IntrinsicStatus), "statusMessage": NewIntrinsic(IntrinsicStatusMessage), "kind": NewIntrinsic(IntrinsicKind), - ".name": NewAttribute("name"), - ".status": NewAttribute("status"), - ".foo.bar": NewAttribute("foo.bar"), - "resource.foo.bar": NewScopedAttribute(AttributeScopeResource, false, "foo.bar"), - "span.foo.bar": NewScopedAttribute(AttributeScopeSpan, false, "foo.bar"), + ".name": NewAttribute("name", false), + ".status": NewAttribute("status", false), + ".foo.bar": NewAttribute("foo.bar", false), + "resource.foo.bar": NewScopedAttribute(AttributeScopeResource, false, "foo.bar", false), + "span.foo.bar": NewScopedAttribute(AttributeScopeSpan, false, "foo.bar", false), } for i, expected := range testCases { actual, err := ParseIdentifier(i) @@ -1329,7 +1380,7 @@ func TestReallyLongQuery(t *testing.T) { // static value query := fmt.Sprintf("{ .a = `%s` }", longVal) - expected := newBinaryOperation(OpEqual, NewAttribute("a"), NewStaticString(longVal)) + expected := newBinaryOperation(OpEqual, NewAttribute("a", false), NewStaticString(longVal)) actual, err := Parse(query) @@ -1338,7 +1389,7 @@ func TestReallyLongQuery(t *testing.T) { // attr name query = fmt.Sprintf("{ .%s = `foo` }", longVal) - expected = newBinaryOperation(OpEqual, NewAttribute(longVal), NewStaticString("foo")) + expected = newBinaryOperation(OpEqual, NewAttribute(longVal, false), NewStaticString("foo")) actual, err = Parse(query) @@ -1365,7 +1416,7 @@ func TestMetrics(t *testing.T) { newPipeline(newSpansetFilter(NewStaticBool(true))), newMetricsAggregate(metricsAggregateCountOverTime, []Attribute{ NewIntrinsic(IntrinsicName), - NewScopedAttribute(AttributeScopeSpan, false, "http.status_code"), + NewScopedAttribute(AttributeScopeSpan, false, "http.status_code", false), }), ), }, @@ -1377,7 +1428,7 @@ func TestMetrics(t *testing.T) { NewIntrinsic(IntrinsicDuration), []Attribute{ NewIntrinsic(IntrinsicName), - NewScopedAttribute(AttributeScopeSpan, false, "http.status_code"), + NewScopedAttribute(AttributeScopeSpan, false, "http.status_code", false), }), ), }, @@ -1390,7 +1441,7 @@ func TestMetrics(t *testing.T) { []float64{0, 0.9, 0.95, 1.0}, []Attribute{ NewIntrinsic(IntrinsicName), - NewScopedAttribute(AttributeScopeSpan, false, "http.status_code"), + NewScopedAttribute(AttributeScopeSpan, false, "http.status_code", false), }), ), }, diff --git a/pkg/traceqlmetrics/metrics.go b/pkg/traceqlmetrics/metrics.go index 3798f6a078a..70fcf9624c8 100644 --- a/pkg/traceqlmetrics/metrics.go +++ b/pkg/traceqlmetrics/metrics.go @@ -211,8 +211,8 @@ func GetMetrics(ctx context.Context, query, groupBy string, spanLimit int, start // Unscoped attribute. Also check span-level, then resource-level. lookups = []traceql.Attribute{ attr, - traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, attr.Name), - traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, attr.Name), + traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, attr.Name, false), + traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, attr.Name, false), } } else { lookups = []traceql.Attribute{attr} diff --git a/tempodb/encoding/vparquet2/block_search_tags.go b/tempodb/encoding/vparquet2/block_search_tags.go index c3eb7267726..ca869225105 100644 --- a/tempodb/encoding/vparquet2/block_search_tags.go +++ b/tempodb/encoding/vparquet2/block_search_tags.go @@ -23,18 +23,18 @@ var translateTagToAttribute = map[string]traceql.Attribute{ // Preserve behavior of v1 tag lookups which directed some attributes // to dedicated columns. - LabelServiceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelServiceName), - LabelCluster: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelCluster), - LabelNamespace: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelNamespace), - LabelPod: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelPod), - LabelContainer: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelContainer), - LabelK8sNamespaceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sNamespaceName), - LabelK8sClusterName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sClusterName), - LabelK8sPodName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sPodName), - LabelK8sContainerName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sContainerName), - LabelHTTPMethod: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPMethod), - LabelHTTPUrl: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPUrl), - LabelHTTPStatusCode: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPStatusCode), + LabelServiceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelServiceName, false), + LabelCluster: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelCluster, false), + LabelNamespace: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelNamespace, false), + LabelPod: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelPod, false), + LabelContainer: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelContainer, false), + LabelK8sNamespaceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sNamespaceName, false), + LabelK8sClusterName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sClusterName, false), + LabelK8sPodName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sPodName, false), + LabelK8sContainerName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sContainerName, false), + LabelHTTPMethod: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPMethod, false), + LabelHTTPUrl: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPUrl, false), + LabelHTTPStatusCode: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPStatusCode, false), } var nonTraceQLAttributes = map[string]string{ @@ -183,7 +183,7 @@ func searchTags(_ context.Context, scope traceql.AttributeScope, cb common.TagsC func (b *backendBlock) SearchTagValues(ctx context.Context, tag string, cb common.TagValuesCallback, opts common.SearchOptions) error { att, ok := translateTagToAttribute[tag] if !ok { - att = traceql.NewAttribute(tag) + att = traceql.NewAttribute(tag, false) } // Wrap to v2-style diff --git a/tempodb/encoding/vparquet2/block_search_tags_test.go b/tempodb/encoding/vparquet2/block_search_tags_test.go index d3905d67530..5e2cf996fdb 100644 --- a/tempodb/encoding/vparquet2/block_search_tags_test.go +++ b/tempodb/encoding/vparquet2/block_search_tags_test.go @@ -109,7 +109,7 @@ func TestBackendBlockSearchTagValuesV2(t *testing.T) { }}, // Trace-level special - {traceql.NewAttribute("root.name"), []traceql.Static{ + {traceql.NewAttribute("root.name", false), []traceql.Static{ traceql.NewStaticString("RootSpan"), }}, diff --git a/tempodb/encoding/vparquet2/block_traceql.go b/tempodb/encoding/vparquet2/block_traceql.go index afbafa11e9d..eec217f4ab9 100644 --- a/tempodb/encoding/vparquet2/block_traceql.go +++ b/tempodb/encoding/vparquet2/block_traceql.go @@ -2252,11 +2252,11 @@ func (c *attributeCollector) KeepGroup(res *parquetquery.IteratorResult) bool { } func newSpanAttr(name string) traceql.Attribute { - return traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, name) + return traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, name, false) } func newResAttr(name string) traceql.Attribute { - return traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, name) + return traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, name, false) } func unionIfNeeded(definitionLevel int, iters []parquetquery.Iterator, pred parquetquery.GroupPredicate) parquetquery.Iterator { diff --git a/tempodb/encoding/vparquet2/block_traceql_meta_test.go b/tempodb/encoding/vparquet2/block_traceql_meta_test.go index fd0738787ed..c592f816982 100644 --- a/tempodb/encoding/vparquet2/block_traceql_meta_test.go +++ b/tempodb/encoding/vparquet2/block_traceql_meta_test.go @@ -97,13 +97,13 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { durationNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].DurationNano, attributes: map[traceql.Attribute]traceql.Static{ // foo not returned because the span didn't match it - traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "bar"): traceql.NewStaticInt(123), - traceql.NewIntrinsic(traceql.IntrinsicDuration): traceql.NewStaticDuration(100 * time.Second), - traceql.NewIntrinsic(traceql.IntrinsicTraceDuration): traceql.NewStaticDuration(100 * time.Millisecond), - traceql.NewIntrinsic(traceql.IntrinsicTraceRootService): traceql.NewStaticString("RootService"), - traceql.NewIntrinsic(traceql.IntrinsicTraceRootSpan): traceql.NewStaticString("RootSpan"), - traceql.NewIntrinsic(traceql.IntrinsicTraceID): traceql.NewStaticString(util.TraceIDToHexString(wantTr.TraceID)), - traceql.NewIntrinsic(traceql.IntrinsicSpanID): traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID)), + traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "bar", false): traceql.NewStaticInt(123), + traceql.NewIntrinsic(traceql.IntrinsicDuration): traceql.NewStaticDuration(100 * time.Second), + traceql.NewIntrinsic(traceql.IntrinsicTraceDuration): traceql.NewStaticDuration(100 * time.Millisecond), + traceql.NewIntrinsic(traceql.IntrinsicTraceRootService): traceql.NewStaticString("RootService"), + traceql.NewIntrinsic(traceql.IntrinsicTraceRootSpan): traceql.NewStaticString("RootSpan"), + traceql.NewIntrinsic(traceql.IntrinsicTraceID): traceql.NewStaticString(util.TraceIDToHexString(wantTr.TraceID)), + traceql.NewIntrinsic(traceql.IntrinsicSpanID): traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID)), }, }, ), diff --git a/tempodb/encoding/vparquet2/wal_block.go b/tempodb/encoding/vparquet2/wal_block.go index 05ecb7c121f..c90f0fcbc80 100644 --- a/tempodb/encoding/vparquet2/wal_block.go +++ b/tempodb/encoding/vparquet2/wal_block.go @@ -595,7 +595,7 @@ func (b *walBlock) SearchTags(ctx context.Context, scope traceql.AttributeScope, func (b *walBlock) SearchTagValues(ctx context.Context, tag string, cb common.TagValuesCallback, opts common.SearchOptions) error { att, ok := translateTagToAttribute[tag] if !ok { - att = traceql.NewAttribute(tag) + att = traceql.NewAttribute(tag, false) } // Wrap to v2-style diff --git a/tempodb/encoding/vparquet3/block_search_tags.go b/tempodb/encoding/vparquet3/block_search_tags.go index 06a6f7c3817..7c2b8688115 100644 --- a/tempodb/encoding/vparquet3/block_search_tags.go +++ b/tempodb/encoding/vparquet3/block_search_tags.go @@ -24,18 +24,18 @@ var translateTagToAttribute = map[string]traceql.Attribute{ // Preserve behavior of v1 tag lookups which directed some attributes // to dedicated columns. - LabelServiceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelServiceName), - LabelCluster: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelCluster), - LabelNamespace: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelNamespace), - LabelPod: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelPod), - LabelContainer: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelContainer), - LabelK8sNamespaceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sNamespaceName), - LabelK8sClusterName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sClusterName), - LabelK8sPodName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sPodName), - LabelK8sContainerName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sContainerName), - LabelHTTPMethod: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPMethod), - LabelHTTPUrl: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPUrl), - LabelHTTPStatusCode: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPStatusCode), + LabelServiceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelServiceName, false), + LabelCluster: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelCluster, false), + LabelNamespace: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelNamespace, false), + LabelPod: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelPod, false), + LabelContainer: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelContainer, false), + LabelK8sNamespaceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sNamespaceName, false), + LabelK8sClusterName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sClusterName, false), + LabelK8sPodName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sPodName, false), + LabelK8sContainerName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sContainerName, false), + LabelHTTPMethod: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPMethod, false), + LabelHTTPUrl: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPUrl, false), + LabelHTTPStatusCode: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPStatusCode, false), } var nonTraceQLAttributes = map[string]string{ @@ -192,7 +192,7 @@ func searchTags(_ context.Context, scope traceql.AttributeScope, cb common.TagsC func (b *backendBlock) SearchTagValues(ctx context.Context, tag string, cb common.TagValuesCallback, opts common.SearchOptions) error { att, ok := translateTagToAttribute[tag] if !ok { - att = traceql.NewAttribute(tag) + att = traceql.NewAttribute(tag, false) } // Wrap to v2-style diff --git a/tempodb/encoding/vparquet3/block_search_tags_test.go b/tempodb/encoding/vparquet3/block_search_tags_test.go index b8ac79db3e0..fc03326e80e 100644 --- a/tempodb/encoding/vparquet3/block_search_tags_test.go +++ b/tempodb/encoding/vparquet3/block_search_tags_test.go @@ -112,7 +112,7 @@ func TestBackendBlockSearchTagValuesV2(t *testing.T) { }}, // Trace-level special - {traceql.NewAttribute("root.name"), []traceql.Static{ + {traceql.NewAttribute("root.name", false), []traceql.Static{ traceql.NewStaticString("RootSpan"), }}, diff --git a/tempodb/encoding/vparquet3/block_traceql.go b/tempodb/encoding/vparquet3/block_traceql.go index 209c757c644..19e3f3dd74b 100644 --- a/tempodb/encoding/vparquet3/block_traceql.go +++ b/tempodb/encoding/vparquet3/block_traceql.go @@ -2568,11 +2568,11 @@ func (c *attributeCollector) KeepGroup(res *parquetquery.IteratorResult) bool { } func newSpanAttr(name string) traceql.Attribute { - return traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, name) + return traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, name, false) } func newResAttr(name string) traceql.Attribute { - return traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, name) + return traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, name, false) } func unionIfNeeded(definitionLevel int, iters []parquetquery.Iterator, pred parquetquery.GroupPredicate) parquetquery.Iterator { diff --git a/tempodb/encoding/vparquet3/block_traceql_meta_test.go b/tempodb/encoding/vparquet3/block_traceql_meta_test.go index a2fe30247f2..6e3f2229cc2 100644 --- a/tempodb/encoding/vparquet3/block_traceql_meta_test.go +++ b/tempodb/encoding/vparquet3/block_traceql_meta_test.go @@ -102,8 +102,8 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { startTimeUnixNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].StartTimeUnixNano, durationNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].DurationNano, spanAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo"), traceql.NewStaticNil()}, - {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "bar"), traceql.NewStaticInt(123)}, + {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo", false), traceql.NewStaticNil()}, + {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "bar", false), traceql.NewStaticInt(123)}, {traceql.NewIntrinsic(traceql.IntrinsicDuration), traceql.NewStaticDuration(100 * time.Second)}, {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID))}, }, @@ -138,7 +138,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID))}, }, resourceAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo"), traceql.NewStaticString("abc")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo", false), traceql.NewStaticString("abc")}, }, traceAttrs: []attrVal{ {traceql.NewIntrinsic(traceql.IntrinsicTraceRootService), traceql.NewStaticString("RootService")}, @@ -168,13 +168,13 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { startTimeUnixNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].StartTimeUnixNano, durationNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].DurationNano, spanAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo"), traceql.NewStaticNil()}, + {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo", false), traceql.NewStaticNil()}, {newSpanAttr(LabelHTTPStatusCode), traceql.NewStaticInt(500)}, // This is the only attribute that matched anything {traceql.NewIntrinsic(traceql.IntrinsicDuration), traceql.NewStaticDuration(100 * time.Second)}, {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID))}, }, resourceAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo"), traceql.NewStaticNil()}, + {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo", false), traceql.NewStaticNil()}, }, traceAttrs: []attrVal{ {traceql.NewIntrinsic(traceql.IntrinsicTraceRootService), traceql.NewStaticString("RootService")}, @@ -206,7 +206,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { startTimeUnixNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].StartTimeUnixNano, durationNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].DurationNano, spanAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo"), traceql.NewStaticString("def")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo", false), traceql.NewStaticString("def")}, {newSpanAttr("float"), traceql.NewStaticFloat(456.78)}, {newSpanAttr("bool"), traceql.NewStaticBool(false)}, {newSpanAttr(LabelHTTPStatusCode), traceql.NewStaticInt(500)}, // This is the only attribute that matched anything @@ -214,7 +214,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID))}, }, resourceAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo"), traceql.NewStaticString("abc")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo", false), traceql.NewStaticString("abc")}, }, traceAttrs: []attrVal{ {traceql.NewIntrinsic(traceql.IntrinsicTraceRootService), traceql.NewStaticString("RootService")}, @@ -228,7 +228,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { startTimeUnixNanos: wantTr.ResourceSpans[1].ScopeSpans[0].Spans[0].StartTimeUnixNano, durationNanos: wantTr.ResourceSpans[1].ScopeSpans[0].Spans[0].DurationNano, spanAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo"), traceql.NewStaticString("ghi")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo", false), traceql.NewStaticString("ghi")}, {newSpanAttr("float"), traceql.NewStaticFloat(456.789)}, {newSpanAttr("bool"), traceql.NewStaticBool(true)}, {newSpanAttr(LabelHTTPStatusCode), traceql.NewStaticInt(501)}, // This is the only attribute that matched anything @@ -236,7 +236,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[1].ScopeSpans[0].Spans[0].SpanID))}, }, resourceAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo"), traceql.NewStaticString("abc2")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo", false), traceql.NewStaticString("abc2")}, }, traceAttrs: []attrVal{ {traceql.NewIntrinsic(traceql.IntrinsicTraceRootService), traceql.NewStaticString("RootService")}, diff --git a/tempodb/encoding/vparquet3/wal_block.go b/tempodb/encoding/vparquet3/wal_block.go index a37add6e10d..1677b8c6e17 100644 --- a/tempodb/encoding/vparquet3/wal_block.go +++ b/tempodb/encoding/vparquet3/wal_block.go @@ -609,7 +609,7 @@ func (b *walBlock) SearchTags(ctx context.Context, scope traceql.AttributeScope, func (b *walBlock) SearchTagValues(ctx context.Context, tag string, cb common.TagValuesCallback, opts common.SearchOptions) error { att, ok := translateTagToAttribute[tag] if !ok { - att = traceql.NewAttribute(tag) + att = traceql.NewAttribute(tag, false) } // Wrap to v2-style diff --git a/tempodb/encoding/vparquet4/block_search_tags.go b/tempodb/encoding/vparquet4/block_search_tags.go index b49748e94b1..6fe7480a5a3 100644 --- a/tempodb/encoding/vparquet4/block_search_tags.go +++ b/tempodb/encoding/vparquet4/block_search_tags.go @@ -24,18 +24,18 @@ var translateTagToAttribute = map[string]traceql.Attribute{ // Preserve behavior of v1 tag lookups which directed some attributes // to dedicated columns. - LabelServiceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelServiceName), - LabelCluster: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelCluster), - LabelNamespace: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelNamespace), - LabelPod: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelPod), - LabelContainer: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelContainer), - LabelK8sNamespaceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sNamespaceName), - LabelK8sClusterName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sClusterName), - LabelK8sPodName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sPodName), - LabelK8sContainerName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sContainerName), - LabelHTTPMethod: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPMethod), - LabelHTTPUrl: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPUrl), - LabelHTTPStatusCode: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPStatusCode), + LabelServiceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelServiceName, false), + LabelCluster: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelCluster, false), + LabelNamespace: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelNamespace, false), + LabelPod: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelPod, false), + LabelContainer: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelContainer, false), + LabelK8sNamespaceName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sNamespaceName, false), + LabelK8sClusterName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sClusterName, false), + LabelK8sPodName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sPodName, false), + LabelK8sContainerName: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sContainerName, false), + LabelHTTPMethod: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPMethod, false), + LabelHTTPUrl: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPUrl, false), + LabelHTTPStatusCode: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPStatusCode, false), } var nonTraceQLAttributes = map[string]string{ @@ -213,7 +213,7 @@ func searchTags(_ context.Context, scope traceql.AttributeScope, cb common.TagsC func (b *backendBlock) SearchTagValues(ctx context.Context, tag string, cb common.TagValuesCallback, opts common.SearchOptions) error { att, ok := translateTagToAttribute[tag] if !ok { - att = traceql.NewAttribute(tag) + att = traceql.NewAttribute(tag, false) } // Wrap to v2-style diff --git a/tempodb/encoding/vparquet4/block_search_tags_test.go b/tempodb/encoding/vparquet4/block_search_tags_test.go index 0ca5a0dcc94..eff596bfbee 100644 --- a/tempodb/encoding/vparquet4/block_search_tags_test.go +++ b/tempodb/encoding/vparquet4/block_search_tags_test.go @@ -112,7 +112,7 @@ func TestBackendBlockSearchTagValuesV2(t *testing.T) { }}, // Trace-level special - {traceql.NewAttribute("root.name"), []traceql.Static{ + {traceql.NewAttribute("root.name", false), []traceql.Static{ traceql.NewStaticString("RootSpan"), }}, diff --git a/tempodb/encoding/vparquet4/block_traceql.go b/tempodb/encoding/vparquet4/block_traceql.go index d786535aaab..923c8d7113d 100644 --- a/tempodb/encoding/vparquet4/block_traceql.go +++ b/tempodb/encoding/vparquet4/block_traceql.go @@ -2661,7 +2661,10 @@ func createAttributeIterator(makeIter makeIterFn, conditions []traceql.Condition // if all conditions must be true we can use a simple join iterator to test the values one column at a time. // len(valueIters) must be 1 to handle queries like `{ span.foo = "x" && span.bar > 1}` if allConditions && len(valueIters) == 1 { - iters := append([]parquetquery.Iterator{makeIter(keyPath, parquetquery.NewStringInPredicate(attrKeys), "key")}, valueIters...) + iters := append([]parquetquery.Iterator{ + makeIter(keyPath, parquetquery.NewStringInPredicate(attrKeys), "key"), + makeIter(keyPath, parquetquery.NewStringInPredicate(attrKeys), "key"), + }, valueIters...) return parquetquery.NewJoinIterator(definitionLevel, iters, &attributeCollector{}, @@ -2669,7 +2672,10 @@ func createAttributeIterator(makeIter makeIterFn, conditions []traceql.Condition } return parquetquery.NewLeftJoinIterator(definitionLevel, - []parquetquery.Iterator{makeIter(keyPath, parquetquery.NewStringInPredicate(attrKeys), "key")}, + []parquetquery.Iterator{ + makeIter(keyPath, parquetquery.NewStringInPredicate(attrKeys), "key"), + makeIter(keyPath, parquetquery.NewStringInPredicate(attrKeys), "key"), + }, valueIters, &attributeCollector{}, parquetquery.WithPool(pqAttrPool)) @@ -3335,23 +3341,23 @@ func (c *linkCollector) KeepGroup(res *parquetquery.IteratorResult) bool { } func newSpanAttr(name string) traceql.Attribute { - return traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, name) + return traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, name, false) } func newResAttr(name string) traceql.Attribute { - return traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, name) + return traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, name, false) } func newInstrumentationAttrs(name string) traceql.Attribute { - return traceql.NewScopedAttribute(traceql.AttributeScopeInstrumentation, false, name) + return traceql.NewScopedAttribute(traceql.AttributeScopeInstrumentation, false, name, false) } func newEventAttr(name string) traceql.Attribute { - return traceql.NewScopedAttribute(traceql.AttributeScopeEvent, false, name) + return traceql.NewScopedAttribute(traceql.AttributeScopeEvent, false, name, false) } func newLinkAttr(name string) traceql.Attribute { - return traceql.NewScopedAttribute(traceql.AttributeScopeLink, false, name) + return traceql.NewScopedAttribute(traceql.AttributeScopeLink, false, name, false) } func unionIfNeeded(definitionLevel int, iters []parquetquery.Iterator, pred parquetquery.GroupPredicate) parquetquery.Iterator { diff --git a/tempodb/encoding/vparquet4/block_traceql_meta_test.go b/tempodb/encoding/vparquet4/block_traceql_meta_test.go index 81457e53262..90b7f110604 100644 --- a/tempodb/encoding/vparquet4/block_traceql_meta_test.go +++ b/tempodb/encoding/vparquet4/block_traceql_meta_test.go @@ -112,8 +112,8 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { startTimeUnixNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].StartTimeUnixNano, durationNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].DurationNano, spanAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo"), traceql.NewStaticNil()}, - {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "bar"), traceql.NewStaticInt(123)}, + {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo", false), traceql.NewStaticNil()}, + {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "bar", false), traceql.NewStaticInt(123)}, {traceql.NewIntrinsic(traceql.IntrinsicDuration), traceql.NewStaticDuration(100 * time.Second)}, {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID))}, }, @@ -148,7 +148,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID))}, }, resourceAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo"), traceql.NewStaticString("abc")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo", false), traceql.NewStaticString("abc")}, }, traceAttrs: []attrVal{ {traceql.NewIntrinsic(traceql.IntrinsicTraceRootService), traceql.NewStaticString("RootService")}, @@ -178,13 +178,13 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { startTimeUnixNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].StartTimeUnixNano, durationNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].DurationNano, spanAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo"), traceql.NewStaticNil()}, + {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo", false), traceql.NewStaticNil()}, {newSpanAttr(LabelHTTPStatusCode), traceql.NewStaticInt(500)}, // This is the only attribute that matched anything {traceql.NewIntrinsic(traceql.IntrinsicDuration), traceql.NewStaticDuration(100 * time.Second)}, {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID))}, }, resourceAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo"), traceql.NewStaticNil()}, + {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo", false), traceql.NewStaticNil()}, }, traceAttrs: []attrVal{ {traceql.NewIntrinsic(traceql.IntrinsicTraceRootService), traceql.NewStaticString("RootService")}, @@ -216,7 +216,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { startTimeUnixNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].StartTimeUnixNano, durationNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].DurationNano, spanAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo"), traceql.NewStaticString("def")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo", false), traceql.NewStaticString("def")}, {newSpanAttr("float"), traceql.NewStaticFloat(456.78)}, {newSpanAttr("bool"), traceql.NewStaticBool(false)}, {newSpanAttr(LabelHTTPStatusCode), traceql.NewStaticInt(500)}, // This is the only attribute that matched anything @@ -224,7 +224,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID))}, }, resourceAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo"), traceql.NewStaticString("abc")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo", false), traceql.NewStaticString("abc")}, }, traceAttrs: []attrVal{ {traceql.NewIntrinsic(traceql.IntrinsicTraceRootService), traceql.NewStaticString("RootService")}, @@ -238,7 +238,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { startTimeUnixNanos: wantTr.ResourceSpans[1].ScopeSpans[0].Spans[0].StartTimeUnixNano, durationNanos: wantTr.ResourceSpans[1].ScopeSpans[0].Spans[0].DurationNano, spanAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo"), traceql.NewStaticString("ghi")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "foo", false), traceql.NewStaticString("ghi")}, {newSpanAttr("float"), traceql.NewStaticFloat(456.789)}, {newSpanAttr("bool"), traceql.NewStaticBool(true)}, {newSpanAttr(LabelHTTPStatusCode), traceql.NewStaticInt(501)}, // This is the only attribute that matched anything @@ -246,7 +246,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[1].ScopeSpans[0].Spans[0].SpanID))}, }, resourceAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo"), traceql.NewStaticString("abc2")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "foo", false), traceql.NewStaticString("abc2")}, }, traceAttrs: []attrVal{ {traceql.NewIntrinsic(traceql.IntrinsicTraceRootService), traceql.NewStaticString("RootService")}, @@ -603,8 +603,8 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { {traceql.NewIntrinsic(traceql.IntrinsicTraceID), traceql.NewStaticString(util.TraceIDToHexString(wantTr.TraceID))}, }, eventAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeEvent, false, "message"), traceql.NewStaticString("exception")}, - {traceql.NewScopedAttribute(traceql.AttributeScopeEvent, false, "message"), traceql.NewStaticString("exception")}, // two events with the same message attr in the same span + {traceql.NewScopedAttribute(traceql.AttributeScopeEvent, false, "message", false), traceql.NewStaticString("exception")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeEvent, false, "message", false), traceql.NewStaticString("exception")}, // two events with the same message attr in the same span }, }, ), @@ -703,7 +703,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { {traceql.NewIntrinsic(traceql.IntrinsicTraceID), traceql.NewStaticString(util.TraceIDToHexString(wantTr.TraceID))}, }, linkAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeLink, false, "opentracing.ref_type"), traceql.NewStaticString("child-of")}, + {traceql.NewScopedAttribute(traceql.AttributeScopeLink, false, "opentracing.ref_type", false), traceql.NewStaticString("child-of")}, }, }, ), @@ -802,7 +802,7 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { {traceql.NewIntrinsic(traceql.IntrinsicTraceID), traceql.NewStaticString(util.TraceIDToHexString(wantTr.TraceID))}, }, instrumentationAttrs: []attrVal{ - {traceql.NewScopedAttribute(traceql.AttributeScopeInstrumentation, false, "scope-attr-int"), traceql.NewStaticInt(101)}, + {traceql.NewScopedAttribute(traceql.AttributeScopeInstrumentation, false, "scope-attr-int", false), traceql.NewStaticInt(101)}, }, }, ), diff --git a/tempodb/encoding/vparquet4/block_traceql_test.go b/tempodb/encoding/vparquet4/block_traceql_test.go index f4a3a1a3bea..631c71a010c 100644 --- a/tempodb/encoding/vparquet4/block_traceql_test.go +++ b/tempodb/encoding/vparquet4/block_traceql_test.go @@ -809,24 +809,24 @@ func flattenForSelectAll(tr *Trace, dcm dedicatedColumnMapping) *traceql.Spanset for _, rs := range tr.ResourceSpans { var rsAttrs []attrVal - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelServiceName), traceql.NewStaticString(rs.Resource.ServiceName)}) - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelCluster), traceql.NewStaticString(*rs.Resource.Cluster)}) - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelNamespace), traceql.NewStaticString(*rs.Resource.Namespace)}) - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelPod), traceql.NewStaticString(*rs.Resource.Pod)}) - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelContainer), traceql.NewStaticString(*rs.Resource.Container)}) - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sClusterName), traceql.NewStaticString(*rs.Resource.K8sClusterName)}) - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sNamespaceName), traceql.NewStaticString(*rs.Resource.K8sNamespaceName)}) - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sPodName), traceql.NewStaticString(*rs.Resource.K8sPodName)}) - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sContainerName), traceql.NewStaticString(*rs.Resource.K8sContainerName)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelServiceName, false), traceql.NewStaticString(rs.Resource.ServiceName)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelCluster, false), traceql.NewStaticString(*rs.Resource.Cluster)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelNamespace, false), traceql.NewStaticString(*rs.Resource.Namespace)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelPod, false), traceql.NewStaticString(*rs.Resource.Pod)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelContainer, false), traceql.NewStaticString(*rs.Resource.Container)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sClusterName, false), traceql.NewStaticString(*rs.Resource.K8sClusterName)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sNamespaceName, false), traceql.NewStaticString(*rs.Resource.K8sNamespaceName)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sPodName, false), traceql.NewStaticString(*rs.Resource.K8sPodName)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, LabelK8sContainerName, false), traceql.NewStaticString(*rs.Resource.K8sContainerName)}) for _, a := range parquetToProtoAttrs(rs.Resource.Attrs) { if arr := a.Value.GetArrayValue(); arr != nil { for _, v := range arr.Values { - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, a.Key), traceql.StaticFromAnyValue(v)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, a.Key, false), traceql.StaticFromAnyValue(v)}) } continue } - rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, a.Key), traceql.StaticFromAnyValue(a.Value)}) + rsAttrs = append(rsAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, a.Key, false), traceql.StaticFromAnyValue(a.Value)}) } dcm.forEach(func(attr string, column dedicatedColumn) { @@ -835,7 +835,7 @@ func flattenForSelectAll(tr *Trace, dcm dedicatedColumnMapping) *traceql.Spanset if v == nil { return } - a := traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, attr) + a := traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, attr, false) s := traceql.StaticFromAnyValue(v) rsAttrs = append(rsAttrs, attrVal{a, s}) } @@ -850,11 +850,11 @@ func flattenForSelectAll(tr *Trace, dcm dedicatedColumnMapping) *traceql.Spanset for _, a := range parquetToProtoAttrs(ss.Scope.Attrs) { if arr := a.Value.GetArrayValue(); arr != nil { for _, v := range arr.Values { - instrumentationAttrs = append(instrumentationAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeInstrumentation, false, a.Key), traceql.StaticFromAnyValue(v)}) + instrumentationAttrs = append(instrumentationAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeInstrumentation, false, a.Key, false), traceql.StaticFromAnyValue(v)}) } continue } - instrumentationAttrs = append(instrumentationAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeInstrumentation, false, a.Key), traceql.StaticFromAnyValue(a.Value)}) + instrumentationAttrs = append(instrumentationAttrs, attrVal{traceql.NewScopedAttribute(traceql.AttributeScopeInstrumentation, false, a.Key, false), traceql.StaticFromAnyValue(a.Value)}) } sortAttrs(instrumentationAttrs) @@ -873,13 +873,13 @@ func flattenForSelectAll(tr *Trace, dcm dedicatedColumnMapping) *traceql.Spanset newS.addSpanAttr(traceql.IntrinsicStatusAttribute, traceql.NewStaticStatus(otlpStatusToTraceqlStatus(uint64(s.StatusCode)))) newS.addSpanAttr(traceql.IntrinsicStatusMessageAttribute, traceql.NewStaticString(s.StatusMessage)) if s.HttpStatusCode != nil { - newS.addSpanAttr(traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPStatusCode), traceql.NewStaticInt(int(*s.HttpStatusCode))) + newS.addSpanAttr(traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPStatusCode, false), traceql.NewStaticInt(int(*s.HttpStatusCode))) } if s.HttpMethod != nil { - newS.addSpanAttr(traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPMethod), traceql.NewStaticString(*s.HttpMethod)) + newS.addSpanAttr(traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPMethod, false), traceql.NewStaticString(*s.HttpMethod)) } if s.HttpUrl != nil { - newS.addSpanAttr(traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPUrl), traceql.NewStaticString(*s.HttpUrl)) + newS.addSpanAttr(traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, LabelHTTPUrl, false), traceql.NewStaticString(*s.HttpUrl)) } dcm.forEach(func(attr string, column dedicatedColumn) { @@ -888,7 +888,7 @@ func flattenForSelectAll(tr *Trace, dcm dedicatedColumnMapping) *traceql.Spanset if v == nil { return } - a := traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, attr) + a := traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, attr, false) s := traceql.StaticFromAnyValue(v) newS.addSpanAttr(a, s) } @@ -897,11 +897,11 @@ func flattenForSelectAll(tr *Trace, dcm dedicatedColumnMapping) *traceql.Spanset for _, a := range parquetToProtoAttrs(s.Attrs) { if arr := a.Value.GetArrayValue(); arr != nil { for _, v := range arr.Values { - newS.addSpanAttr(traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, a.Key), traceql.StaticFromAnyValue(v)) + newS.addSpanAttr(traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, a.Key, false), traceql.StaticFromAnyValue(v)) } continue } - newS.addSpanAttr(traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, a.Key), traceql.StaticFromAnyValue(a.Value)) + newS.addSpanAttr(traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, a.Key, false), traceql.StaticFromAnyValue(a.Value)) } sortAttrs(newS.spanAttrs) diff --git a/tempodb/encoding/vparquet4/wal_block.go b/tempodb/encoding/vparquet4/wal_block.go index 7ae8f5836e0..a1fe721030e 100644 --- a/tempodb/encoding/vparquet4/wal_block.go +++ b/tempodb/encoding/vparquet4/wal_block.go @@ -610,7 +610,7 @@ func (b *walBlock) SearchTags(ctx context.Context, scope traceql.AttributeScope, func (b *walBlock) SearchTagValues(ctx context.Context, tag string, cb common.TagValuesCallback, opts common.SearchOptions) error { att, ok := translateTagToAttribute[tag] if !ok { - att = traceql.NewAttribute(tag) + att = traceql.NewAttribute(tag, false) } // Wrap to v2-style diff --git a/tempodb/tempodb_search_test.go b/tempodb/tempodb_search_test.go index a6eb0778db5..3de350a6dbc 100644 --- a/tempodb/tempodb_search_test.go +++ b/tempodb/tempodb_search_test.go @@ -1311,13 +1311,13 @@ func tagValuesRunner(t *testing.T, _ *tempopb.Trace, _ *tempopb.TraceSearchMetad }{ { name: "no matches", - tag: traceql.NewAttribute("resource.service.name"), + tag: traceql.NewAttribute("resource.service.name", false), query: "{ span.foo = `bar` }", expected: []tempopb.TagValue{}, }, { name: "no filtering all service.names", - tag: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "service.name"), + tag: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "service.name", false), query: "{}", expected: []tempopb.TagValue{ {Type: "string", Value: "RootService"}, @@ -1329,7 +1329,7 @@ func tagValuesRunner(t *testing.T, _ *tempopb.Trace, _ *tempopb.TraceSearchMetad }, { name: "resource filtered by resource", - tag: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "service.name"), + tag: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "service.name", false), query: "{ resource.cluster = `MyCluster` }", expected: []tempopb.TagValue{ {Type: "string", Value: "MyService"}, @@ -1337,7 +1337,7 @@ func tagValuesRunner(t *testing.T, _ *tempopb.Trace, _ *tempopb.TraceSearchMetad }, { name: "span filtered by resource", - tag: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "span-dedicated.01"), + tag: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "span-dedicated.01", false), query: "{ resource.cluster = `MyCluster` }", expected: []tempopb.TagValue{ {Type: "string", Value: "span-1a"}, @@ -1345,7 +1345,7 @@ func tagValuesRunner(t *testing.T, _ *tempopb.Trace, _ *tempopb.TraceSearchMetad }, { name: "span filtered by span", - tag: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "span-dedicated.01"), + tag: traceql.NewScopedAttribute(traceql.AttributeScopeSpan, false, "span-dedicated.01", false), query: "{ span.http.url = `url/Hello/World` }", expected: []tempopb.TagValue{ {Type: "string", Value: "span-1a"}, @@ -1353,7 +1353,7 @@ func tagValuesRunner(t *testing.T, _ *tempopb.Trace, _ *tempopb.TraceSearchMetad }, { name: "resource filtered by span", - tag: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "service.name"), + tag: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "service.name", false), query: "{ span.foo = `Bar` }", expected: []tempopb.TagValue{ {Type: "string", Value: "MyService"}, @@ -1362,7 +1362,7 @@ func tagValuesRunner(t *testing.T, _ *tempopb.Trace, _ *tempopb.TraceSearchMetad }, { name: "multiple conditions", - tag: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "res-dedicated.01"), + tag: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "res-dedicated.01", false), query: "{ resource.res-dedicated.02 = `res-2a` && span.http.status_code = 500 }", expected: []tempopb.TagValue{ {Type: "string", Value: "res-1a"}, @@ -1370,7 +1370,7 @@ func tagValuesRunner(t *testing.T, _ *tempopb.Trace, _ *tempopb.TraceSearchMetad }, { name: "unscoped not supported", // todo: add support for unscoped. currently it falls back to old logic and returns everything - tag: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "service.name"), + tag: traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, "service.name", false), query: "{ .foo = `Bar` }", expected: []tempopb.TagValue{ {Type: "string", Value: "RootService"},