diff --git a/CHANGELOG.md b/CHANGELOG.md index df5ecb216f9..c952daed001 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * [FEATURE] New encoding vParquet3 with support for dedicated attribute columns (@mapno, @stoewer) [#2649](https://github.com/grafana/tempo/pull/2649) * [FEATURE] Add filtering support to Generic Forwarding [#2742](https://github.com/grafana/tempo/pull/2742) (@Blinkuu) * [FEATURE] Add cli command to print out summary of large traces [#2775](https://github.com/grafana/tempo/pull/2775) (@ie-pham) +* [FEATURE] Added not structural operators to TraceQL: !>, !<, and !~ [#2993](https://github.com/grafana/tempo/pull/2993) (@joe-elliott) * [CHANGE] Update Go to 1.21 [#2486](https://github.com/grafana/tempo/pull/2829) (@zalegrala) * [CHANGE] Make metrics-generator ingestion slack per tenant [#2589](https://github.com/grafana/tempo/pull/2589) (@ie-pham) * [CHANGE] Moved the tempo_ingester_traces_created_total metric to be incremented when a trace is cut to the wal [#2884](https://github.com/grafana/tempo/pull/2884) (@joe-elliott) diff --git a/docs/sources/tempo/traceql/_index.md b/docs/sources/tempo/traceql/_index.md index 738cefd990e..0e61ca4bb06 100644 --- a/docs/sources/tempo/traceql/_index.md +++ b/docs/sources/tempo/traceql/_index.md @@ -208,13 +208,14 @@ The second expression returns no traces because it's impossible for a single spa ### Structural -These spanset operators look at the structure of a trace and the relationship between the spans. +These spanset operators look at the structure of a trace and the relationship between the spans. Structural operators ALWAYS return +matches from the right hand side of the operator. - `{condA} >> {condB}` - The descendant operator (`>>`) looks for spans matching `{condB}` that are descendants of a span matching `{condA}` - `{condA} << {condB}` - The ancestor operator (`<<`) looks for spans matching `{condB}` that are ancestor of a span matching `{condA}` - `{condA} > {condB}` - The child operator (`>`) looks for spans matching `{condB}` that are direct child spans of a parent matching `{condA}` - `{condA} < {condB}` - The parent operator (`<`) looks for spans matching `{condB}` that are direct parent spans of a child matching `{condA}` -- `{condA} ~ {condB}` - The sibling operator (`~`) checks that spans matching `{condA}` and `{condB}` are siblings of the same parent span. +- `{condA} ~ {condB}` - The sibling operator (`~`) looks at spans matching `{condB}` that have at least one sibling matching `{condA}`. For example, to find a trace where a specific HTTP API interacted with a specific database: @@ -222,6 +223,29 @@ For example, to find a trace where a specific HTTP API interacted with a specifi { span.http.url = "/path/of/api" } >> { span.db.name = "db-shard-001" } ``` +### Experimental Structural + +These spanset operators look at the structure of a trace and the relationship between the spans. They are marked experimental because they +are known to sometimes return false positives. However, they can be very useful (see examples below). We encourage users to try them and give feedback. + +- `{condA} !>> {condB}` - The not-descendant operator (`!>>`) looks for spans matching `{condB}` that are not descendant spans of a parent matching `{condA}` +- `{condA} !<< {condB}` - The not-ancestor operator (`!<<`) looks for spans matching `{condB}` that are not ancestor spans of a child matching `{condA}` +- `{condA} !> {condB}` - The not-child operator (`!>`) looks for spans matching `{condB}` that are not direct child spans of a parent matching `{condA}` +- `{condA} !< {condB}` - The not-parent operator (`!<`) looks for spans matching `{condB}` that are not direct parent spans of a child matching `{condA}` +- `{condA} !~ {condB}` - The not-sibling operator (`!~`) looks that spans matching `{condB}` that do not have at least one sibling matching `{condA}`. + +For example, to find a trace with a leaf span in the service "foo": + +``` +{ } !< { resource.service.name = "foo" } +``` + +To find a span that is the last error in a series of cascading errors: + +``` +{ status = error } !< { status = error } +``` + ## Aggregators So far, all of the example queries expressions have been about individual spans. You can use aggregate functions to ask questions about a set of spans. These currently consist of: diff --git a/pkg/traceql/ast.go b/pkg/traceql/ast.go index 7bbe837564f..ced59a785d0 100644 --- a/pkg/traceql/ast.go +++ b/pkg/traceql/ast.go @@ -234,15 +234,15 @@ type SpansetOperation struct { func (o SpansetOperation) extractConditions(request *FetchSpansRequest) { switch o.Op { - case OpSpansetDescendant, OpSpansetAncestor: + case OpSpansetDescendant, OpSpansetAncestor, OpSpansetNotDescendant, OpSpansetNotAncestor: request.Conditions = append(request.Conditions, Condition{ Attribute: NewIntrinsic(IntrinsicStructuralDescendant), }) - case OpSpansetChild, OpSpansetParent: + case OpSpansetChild, OpSpansetParent, OpSpansetNotChild, OpSpansetNotParent: request.Conditions = append(request.Conditions, Condition{ Attribute: NewIntrinsic(IntrinsicStructuralChild), }) - case OpSpansetSibling: + case OpSpansetSibling, OpSpansetNotSibling: request.Conditions = append(request.Conditions, Condition{ Attribute: NewIntrinsic(IntrinsicStructuralSibling), }) diff --git a/pkg/traceql/ast_execute.go b/pkg/traceql/ast_execute.go index ece3651045a..ca2ad337c91 100644 --- a/pkg/traceql/ast_execute.go +++ b/pkg/traceql/ast_execute.go @@ -85,6 +85,9 @@ func (o SpansetOperation) evaluate(input []*Spanset) (output []*Spanset, err err return nil, err } + var relFn func(l, r Span) bool + var falseForAll bool + switch o.Op { case OpSpansetAnd: if len(lhs) > 0 && len(rhs) > 0 { @@ -100,76 +103,54 @@ func (o SpansetOperation) evaluate(input []*Spanset) (output []*Spanset, err err output = append(output, matchingSpanset) } + // relationship operators all set relFn which is used by below code + // to perform the operation + case OpSpansetNotDescendant: + falseForAll = true + fallthrough case OpSpansetDescendant: - spans, err := o.joinSpansets(lhs, rhs, func(l, r Span) bool { + relFn = func(l, r Span) bool { return r.DescendantOf(l) - }) - if err != nil { - return nil, err - } - - if len(spans) > 0 { - // Clone here to capture previously computed aggregates, grouped attrs, etc. - // Copy spans to new slice because of internal buffering. - matchingSpanset := input[i].clone() - matchingSpanset.Spans = append([]Span(nil), spans...) - output = append(output, matchingSpanset) } + case OpSpansetNotAncestor: + falseForAll = true + fallthrough case OpSpansetAncestor: - spans, err := o.joinSpansets(lhs, rhs, func(l, r Span) bool { - // In case of ancestor the lhs becomes descendant of rhs + relFn = func(l, r Span) bool { return l.DescendantOf(r) - }) - if err != nil { - return nil, err - } - - if len(spans) > 0 { - // Clone here to capture previously computed aggregates, grouped attrs, etc. - // Copy spans to new slice because of internal buffering. - matchingSpanset := input[i].clone() - matchingSpanset.Spans = append([]Span(nil), spans...) - output = append(output, matchingSpanset) } + case OpSpansetNotChild: + falseForAll = true + fallthrough case OpSpansetChild: - spans, err := o.joinSpansets(lhs, rhs, func(l, r Span) bool { + relFn = func(l, r Span) bool { return r.ChildOf(l) - }) - if err != nil { - return nil, err - } - - if len(spans) > 0 { - // Clone here to capture previously computed aggregates, grouped attrs, etc. - // Copy spans to new slice because of internal buffering. - matchingSpanset := input[i].clone() - matchingSpanset.Spans = append([]Span(nil), spans...) - output = append(output, matchingSpanset) } + case OpSpansetNotParent: + falseForAll = true + fallthrough case OpSpansetParent: - spans, err := o.joinSpansets(lhs, rhs, func(l, r Span) bool { - // In case of parent the lhs becomes child of rhs + relFn = func(l, r Span) bool { return l.ChildOf(r) - }) - if err != nil { - return nil, err - } - - if len(spans) > 0 { - // Clone here to capture previously computed aggregates, grouped attrs, etc. - // Copy spans to new slice because of internal buffering. - matchingSpanset := input[i].clone() - matchingSpanset.Spans = append([]Span(nil), spans...) - output = append(output, matchingSpanset) } + case OpSpansetNotSibling: + falseForAll = true + fallthrough case OpSpansetSibling: - spans, err := o.joinSpansets(lhs, rhs, func(l, r Span) bool { + relFn = func(l, r Span) bool { return r.SiblingOf(l) - }) + } + default: + return nil, fmt.Errorf("spanset operation (%v) not supported", o.Op) + } + + // if relFn was set up above we are doing a relationship operation. + if relFn != nil { + spans, err := o.joinSpansets(lhs, rhs, falseForAll, relFn) if err != nil { return nil, err } @@ -181,9 +162,6 @@ func (o SpansetOperation) evaluate(input []*Spanset) (output []*Spanset, err err matchingSpanset.Spans = append([]Span(nil), spans...) output = append(output, matchingSpanset) } - - default: - return nil, fmt.Errorf("spanset operation (%v) not supported", o.Op) } } @@ -193,7 +171,7 @@ func (o SpansetOperation) evaluate(input []*Spanset) (output []*Spanset, err err // joinSpansets compares all pairwise combinations of the inputs and returns the right-hand side // where the eval callback returns true. For now the behavior is only defined when there is exactly one // spanset on both sides and will return an error if multiple spansets are present. -func (o *SpansetOperation) joinSpansets(lhs, rhs []*Spanset, eval func(l, r Span) bool) ([]Span, error) { +func (o *SpansetOperation) joinSpansets(lhs, rhs []*Spanset, falseForAll bool, eval func(l, r Span) bool) ([]Span, error) { if len(lhs) < 1 || len(rhs) < 1 { return nil, nil } @@ -202,13 +180,15 @@ func (o *SpansetOperation) joinSpansets(lhs, rhs []*Spanset, eval func(l, r Span return nil, errSpansetOperationMultiple } - return o.joinSpansAndReturnRHS(lhs[0].Spans, rhs[0].Spans, eval), nil + return o.joinSpansAndReturnRHS(lhs[0].Spans, rhs[0].Spans, falseForAll, eval), nil } // joinSpansAndReturnRHS compares all pairwise combinations of the inputs and returns the right-hand side // spans where the eval callback returns true. Uses and internal buffer and output is only valid until // the next call. Destructively edits the RHS slice for performance. -func (o *SpansetOperation) joinSpansAndReturnRHS(lhs, rhs []Span, eval func(l, r Span) bool) []Span { +// falseForAll indicates that the spans on the RHS should only be returned if relFn returns +// false for all on the LHS. otherwise spans on the RHS are returned if there are any matches on the lhs +func (o *SpansetOperation) joinSpansAndReturnRHS(lhs, rhs []Span, falseForAll bool, eval func(l, r Span) bool) []Span { if len(lhs) == 0 || len(rhs) == 0 { return nil } @@ -216,13 +196,18 @@ func (o *SpansetOperation) joinSpansAndReturnRHS(lhs, rhs []Span, eval func(l, r o.matchingSpansBuffer = o.matchingSpansBuffer[:0] for _, r := range rhs { + matches := false for _, l := range lhs { if eval(l, r) { // Returns RHS - o.matchingSpansBuffer = append(o.matchingSpansBuffer, r) + matches = true break } } + if matches && !falseForAll || // return RHS if there are any matches on the LHS + !matches && falseForAll { // return RHS if there are no matches on the LHS + o.matchingSpansBuffer = append(o.matchingSpansBuffer, r) + } } return o.matchingSpansBuffer diff --git a/pkg/traceql/ast_execute_test.go b/pkg/traceql/ast_execute_test.go index 1fe1e62e6fe..fd934f5144f 100644 --- a/pkg/traceql/ast_execute_test.go +++ b/pkg/traceql/ast_execute_test.go @@ -415,6 +415,81 @@ func TestSpansetOperationEvaluate(t *testing.T) { }}, }, }, + { + "{ } !< { .child }", + []*Spanset{ + {Spans: []Span{ + newMockSpan([]byte{1}).WithAttrBool("parent", true).WithNestedSetInfo(0, 1, 4), + newMockSpan([]byte{2}).WithAttrBool("child", true).WithNestedSetInfo(1, 2, 3), + newMockSpan([]byte{2}).WithAttrBool("child", true).WithNestedSetInfo(0, 1, 4), + }}, + }, + []*Spanset{ + {Spans: []Span{ + newMockSpan([]byte{2}).WithAttrBool("child", true).WithNestedSetInfo(1, 2, 3), + }}, + }, + }, + { + "{ } !> { .parent }", + []*Spanset{ + {Spans: []Span{ + newMockSpan([]byte{1}).WithAttrBool("parent", true).WithNestedSetInfo(0, 1, 4), + newMockSpan([]byte{1}).WithAttrBool("parent", true).WithNestedSetInfo(1, 2, 3), + newMockSpan([]byte{2}).WithAttrBool("child", true).WithNestedSetInfo(1, 2, 3), + }}, + }, + []*Spanset{ + {Spans: []Span{ + newMockSpan([]byte{1}).WithAttrBool("parent", true).WithNestedSetInfo(0, 1, 4), + }}, + }, + }, + { + "{ .child1 } !~ { .child2 }", + []*Spanset{ + {Spans: []Span{ + newMockSpan([]byte{1}).WithAttrBool("child1", true).WithNestedSetInfo(1, 2, 3), + newMockSpan([]byte{1}).WithAttrBool("child2", true).WithNestedSetInfo(1, 4, 5), + newMockSpan([]byte{1}).WithAttrBool("child2", true).WithNestedSetInfo(4, 5, 6), + }}, + }, + []*Spanset{ + {Spans: []Span{ + newMockSpan([]byte{1}).WithAttrBool("child2", true).WithNestedSetInfo(4, 5, 6), + }}, + }, + }, + { + "{ } !<< { .child }", + []*Spanset{ + {Spans: []Span{ + newMockSpan([]byte{1}).WithAttrBool("parent", true).WithNestedSetInfo(0, 1, 4), + newMockSpan([]byte{2}).WithAttrBool("child", true).WithNestedSetInfo(1, 2, 3), + newMockSpan([]byte{2}).WithAttrBool("child", true).WithNestedSetInfo(0, 1, 4), + }}, + }, + []*Spanset{ + {Spans: []Span{ + newMockSpan([]byte{2}).WithAttrBool("child", true).WithNestedSetInfo(1, 2, 3), + }}, + }, + }, + { + "{ } !>> { .parent }", + []*Spanset{ + {Spans: []Span{ + newMockSpan([]byte{1}).WithAttrBool("parent", true).WithNestedSetInfo(0, 1, 4), + newMockSpan([]byte{1}).WithAttrBool("parent", true).WithNestedSetInfo(1, 2, 3), + newMockSpan([]byte{2}).WithAttrBool("child", true).WithNestedSetInfo(1, 2, 3), + }}, + }, + []*Spanset{ + {Spans: []Span{ + newMockSpan([]byte{1}).WithAttrBool("parent", true).WithNestedSetInfo(0, 1, 4), + }}, + }, + }, { // tests that child operators do not modify the spanset "{ } > { } > { } > { }", []*Spanset{ diff --git a/pkg/traceql/ast_validate.go b/pkg/traceql/ast_validate.go index ead581e9d6d..fb18ecc97b5 100644 --- a/pkg/traceql/ast_validate.go +++ b/pkg/traceql/ast_validate.go @@ -179,11 +179,19 @@ func (o BinaryOperation) validate() error { return fmt.Errorf("illegal operation for the given types: %s", o.String()) } + // this condition may not be possible to hit since it's not parseable. + // however, if we did somehow end up this situation, it would be good to return + // a reasonable error switch o.Op { case OpSpansetChild, OpSpansetParent, OpSpansetDescendant, OpSpansetAncestor, + OpSpansetNotChild, + OpSpansetNotParent, + OpSpansetNotSibling, + OpSpansetNotAncestor, + OpSpansetNotDescendant, OpSpansetSibling: return newUnsupportedError(fmt.Sprintf("binary operation (%v)", o.Op)) } diff --git a/pkg/traceql/enum_operators.go b/pkg/traceql/enum_operators.go index dab6673e113..aaa0d11fe54 100644 --- a/pkg/traceql/enum_operators.go +++ b/pkg/traceql/enum_operators.go @@ -30,6 +30,11 @@ const ( OpSpansetAnd OpSpansetUnion OpSpansetSibling + OpSpansetNotChild + OpSpansetNotParent + OpSpansetNotSibling + OpSpansetNotAncestor + OpSpansetNotDescendant ) func (op Operator) isBoolean() bool { @@ -163,6 +168,16 @@ func (op Operator) String() string { return "~" case OpSpansetUnion: return "||" + case OpSpansetNotChild: + return "!>" + case OpSpansetNotParent: + return "!<" + case OpSpansetNotSibling: + return "!~" + case OpSpansetNotAncestor: + return "!<<" + case OpSpansetNotDescendant: + return "!>>" } return fmt.Sprintf("operator(%d)", op) diff --git a/pkg/traceql/enum_operators_test.go b/pkg/traceql/enum_operators_test.go index d69404c8c61..f7feeb739b2 100644 --- a/pkg/traceql/enum_operators_test.go +++ b/pkg/traceql/enum_operators_test.go @@ -35,6 +35,11 @@ func TestOperatorIsBoolean(t *testing.T) { {OpSpansetAnd, false}, {OpSpansetUnion, false}, {OpSpansetSibling, false}, + {OpSpansetNotChild, false}, + {OpSpansetNotParent, false}, + {OpSpansetNotSibling, false}, + {OpSpansetNotAncestor, false}, + {OpSpansetNotDescendant, false}, } for _, tc := range tt { @@ -148,6 +153,9 @@ func TestOperatorUnaryTypesValid(t *testing.T) { {OpSpansetAnd, TypeInt, false}, {OpSpansetUnion, TypeInt, false}, {OpSpansetSibling, TypeInt, false}, + {OpSpansetNotChild, TypeInt, false}, + {OpSpansetNotParent, TypeInt, false}, + {OpSpansetNotSibling, TypeInt, false}, // not {OpNot, TypeBoolean, true}, {OpNot, TypeInt, false}, diff --git a/pkg/traceql/expr.y b/pkg/traceql/expr.y index d3f3ef90cb1..6d2030cb4e7 100644 --- a/pkg/traceql/expr.y +++ b/pkg/traceql/expr.y @@ -84,7 +84,7 @@ import ( // Operators are listed with increasing precedence. %left PIPE %left AND OR -%left EQ NEQ LT LTE GT GTE NRE RE DESC ANCE TILDE +%left EQ NEQ LT LTE GT GTE NRE RE DESC ANCE SIBL NOT_CHILD NOT_PARENT NOT_DESC NOT_ANCE %left ADD SUB %left NOT %left MUL DIV MOD @@ -111,7 +111,12 @@ spansetPipelineExpression: // shares the same operators as spansetExpression. sp | spansetPipelineExpression DESC spansetPipelineExpression { $$ = newSpansetOperation(OpSpansetDescendant, $1, $3) } | spansetPipelineExpression ANCE spansetPipelineExpression { $$ = newSpansetOperation(OpSpansetAncestor, $1, $3) } | spansetPipelineExpression OR spansetPipelineExpression { $$ = newSpansetOperation(OpSpansetUnion, $1, $3) } - | spansetPipelineExpression TILDE spansetPipelineExpression { $$ = newSpansetOperation(OpSpansetSibling, $1, $3) } + | spansetPipelineExpression SIBL spansetPipelineExpression { $$ = newSpansetOperation(OpSpansetSibling, $1, $3) } + | spansetPipelineExpression NOT_CHILD spansetPipelineExpression { $$ = newSpansetOperation(OpSpansetNotChild, $1, $3) } + | spansetPipelineExpression NOT_PARENT spansetPipelineExpression { $$ = newSpansetOperation(OpSpansetNotParent, $1, $3) } + | spansetPipelineExpression NOT_DESC spansetPipelineExpression { $$ = newSpansetOperation(OpSpansetNotDescendant, $1, $3) } + | spansetPipelineExpression NOT_ANCE spansetPipelineExpression { $$ = newSpansetOperation(OpSpansetNotAncestor, $1, $3) } + | spansetPipelineExpression NRE spansetPipelineExpression { $$ = newSpansetOperation(OpSpansetNotSibling, $1, $3) } | wrappedSpansetPipeline { $$ = $1 } ; @@ -155,7 +160,14 @@ spansetExpression: // shares the same operators as scalarPipelineExpression. spl | spansetExpression DESC spansetExpression { $$ = newSpansetOperation(OpSpansetDescendant, $1, $3) } | spansetExpression ANCE spansetExpression { $$ = newSpansetOperation(OpSpansetAncestor, $1, $3) } | spansetExpression OR spansetExpression { $$ = newSpansetOperation(OpSpansetUnion, $1, $3) } - | spansetExpression TILDE spansetExpression { $$ = newSpansetOperation(OpSpansetSibling, $1, $3) } + | spansetExpression SIBL spansetExpression { $$ = newSpansetOperation(OpSpansetSibling, $1, $3) } + + | spansetExpression NOT_CHILD spansetExpression { $$ = newSpansetOperation(OpSpansetNotChild, $1, $3) } + | spansetExpression NOT_PARENT spansetExpression { $$ = newSpansetOperation(OpSpansetNotParent, $1, $3) } + | spansetExpression NRE spansetExpression { $$ = newSpansetOperation(OpSpansetNotSibling, $1, $3) } + | spansetExpression NOT_ANCE spansetExpression { $$ = newSpansetOperation(OpSpansetNotAncestor, $1, $3) } + | spansetExpression NOT_DESC spansetExpression { $$ = newSpansetOperation(OpSpansetNotDescendant, $1, $3) } + | spansetFilter { $$ = $1 } ; diff --git a/pkg/traceql/expr.y.go b/pkg/traceql/expr.y.go index 44f54531929..e44069347db 100644 --- a/pkg/traceql/expr.y.go +++ b/pkg/traceql/expr.y.go @@ -105,14 +105,18 @@ const NRE = 57400 const RE = 57401 const DESC = 57402 const ANCE = 57403 -const TILDE = 57404 -const ADD = 57405 -const SUB = 57406 -const NOT = 57407 -const MUL = 57408 -const DIV = 57409 -const MOD = 57410 -const POW = 57411 +const SIBL = 57404 +const NOT_CHILD = 57405 +const NOT_PARENT = 57406 +const NOT_DESC = 57407 +const NOT_ANCE = 57408 +const ADD = 57409 +const SUB = 57410 +const NOT = 57411 +const MUL = 57412 +const DIV = 57413 +const MOD = 57414 +const POW = 57415 var yyToknames = [...]string{ "$end", @@ -176,7 +180,11 @@ var yyToknames = [...]string{ "RE", "DESC", "ANCE", - "TILDE", + "SIBL", + "NOT_CHILD", + "NOT_PARENT", + "NOT_DESC", + "NOT_ANCE", "ADD", "SUB", "NOT", @@ -196,125 +204,135 @@ var yyExca = [...]int{ -1, 1, 1, -1, -2, 0, - -1, 203, - 13, 57, - -2, 65, + -1, 223, + 13, 67, + -2, 75, } const yyPrivate = 57344 -const yyLast = 684 +const yyLast = 752 var yyAct = [...]int{ - 72, 5, 201, 2, 6, 8, 7, 181, 18, 235, - 68, 45, 44, 168, 169, 55, 170, 171, 172, 181, - 63, 64, 141, 65, 66, 67, 68, 13, 146, 142, - 117, 28, 239, 118, 121, 119, 141, 48, 132, 134, - 135, 136, 137, 138, 139, 238, 182, 183, 173, 174, - 175, 176, 177, 178, 180, 179, 144, 236, 28, 168, - 169, 229, 170, 171, 172, 181, 170, 171, 172, 181, - 164, 166, 142, 76, 184, 185, 186, 228, 63, 64, - 227, 65, 66, 67, 68, 65, 66, 67, 68, 226, - 156, 158, 159, 160, 161, 162, 163, 50, 51, 190, - 52, 53, 54, 55, 207, 208, 50, 51, 200, 52, - 53, 54, 55, 193, 194, 195, 196, 197, 52, 53, - 54, 55, 145, 148, 198, 173, 174, 175, 176, 177, - 178, 180, 179, 191, 192, 198, 168, 169, 149, 170, - 171, 172, 181, 17, 117, 133, 231, 118, 121, 119, - 199, 203, 205, 36, 41, 125, 116, 38, 115, 37, - 38, 114, 37, 39, 40, 42, 39, 40, 42, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 199, 56, 57, 58, 59, - 60, 61, 113, 112, 70, 69, 62, 63, 64, 230, - 65, 66, 67, 68, 45, 189, 45, 205, 49, 237, - 182, 183, 173, 174, 175, 176, 177, 178, 180, 179, - 109, 110, 111, 168, 169, 188, 170, 171, 172, 181, - 48, 143, 48, 79, 80, 81, 85, 105, 187, 71, - 73, 78, 77, 84, 82, 83, 87, 86, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 101, 100, 102, 103, 104, 108, 106, 107, 36, 41, - 47, 16, 38, 4, 37, 12, 10, 165, 39, 40, - 42, 120, 234, 1, 79, 80, 81, 85, 105, 0, - 0, 73, 74, 75, 84, 82, 83, 87, 86, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 101, 100, 102, 103, 104, 108, 106, 107, 182, - 183, 173, 174, 175, 176, 177, 178, 180, 179, 233, - 0, 0, 168, 169, 0, 170, 171, 172, 181, 0, - 0, 29, 34, 74, 75, 31, 0, 30, 31, 232, - 30, 32, 33, 35, 32, 33, 35, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 182, 183, 173, 174, - 175, 176, 177, 178, 180, 179, 225, 0, 0, 168, - 169, 0, 170, 171, 172, 181, 182, 183, 173, 174, - 175, 176, 177, 178, 180, 179, 206, 0, 0, 168, - 169, 0, 170, 171, 172, 181, 0, 0, 0, 0, - 0, 0, 0, 182, 183, 173, 174, 175, 176, 177, - 178, 180, 179, 167, 43, 3, 168, 169, 0, 170, - 171, 172, 181, 182, 183, 173, 174, 175, 176, 177, - 178, 180, 179, 146, 0, 0, 168, 169, 0, 170, - 171, 172, 181, 0, 124, 126, 127, 128, 129, 130, - 131, 0, 182, 183, 173, 174, 175, 176, 177, 178, - 180, 179, 0, 0, 0, 168, 169, 0, 170, 171, - 172, 181, 56, 57, 58, 59, 60, 61, 0, 0, - 0, 0, 0, 63, 64, 0, 65, 66, 67, 68, - 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, - 0, 50, 51, 0, 52, 53, 54, 55, 19, 20, - 21, 0, 17, 0, 122, 0, 19, 20, 21, 0, - 17, 0, 204, 0, 19, 20, 21, 0, 17, 0, - 202, 0, 0, 0, 19, 20, 21, 0, 17, 0, - 9, 0, 23, 26, 24, 25, 27, 14, 123, 15, - 23, 26, 24, 25, 27, 14, 140, 15, 23, 26, - 24, 25, 27, 14, 0, 15, 22, 0, 23, 26, - 24, 25, 27, 14, 22, 15, 0, 19, 20, 21, - 0, 17, 22, 122, 19, 20, 21, 0, 0, 0, - 157, 0, 22, 29, 34, 46, 11, 31, 0, 30, - 0, 0, 0, 32, 33, 35, 0, 0, 0, 0, - 0, 23, 26, 24, 25, 27, 0, 0, 23, 26, - 24, 25, 27, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, - 0, 0, 22, 0, 0, 147, 150, 151, 152, 153, - 154, 155, 79, 80, 81, 85, 0, 0, 0, 149, - 0, 0, 84, 82, 83, 87, 86, 88, 89, 90, - 91, 92, 93, 94, + 82, 5, 221, 2, 6, 8, 7, 18, 201, 78, + 65, 55, 54, 162, 86, 28, 188, 189, 255, 190, + 191, 192, 201, 190, 191, 192, 201, 13, 259, 258, + 127, 161, 249, 128, 131, 129, 248, 58, 75, 76, + 77, 78, 247, 147, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 202, 203, 193, 194, 195, + 196, 197, 198, 200, 199, 73, 74, 28, 75, 76, + 77, 78, 188, 189, 168, 190, 191, 192, 201, 246, + 184, 186, 227, 228, 204, 205, 206, 62, 63, 64, + 65, 256, 66, 67, 68, 69, 70, 71, 254, 213, + 176, 178, 179, 180, 181, 182, 183, 73, 74, 165, + 75, 76, 77, 78, 60, 61, 220, 62, 63, 64, + 65, 169, 88, 161, 214, 215, 216, 217, 210, 17, + 135, 148, 126, 125, 218, 202, 203, 193, 194, 195, + 196, 197, 198, 200, 199, 19, 20, 21, 124, 17, + 218, 132, 188, 189, 123, 190, 191, 192, 201, 162, + 219, 122, 211, 212, 127, 80, 79, 128, 131, 129, + 223, 87, 225, 119, 120, 121, 253, 251, 57, 23, + 26, 24, 25, 27, 14, 133, 15, 166, 250, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 219, 209, 22, 208, 207, + 16, 72, 4, 202, 203, 193, 194, 195, 196, 197, + 198, 200, 199, 59, 55, 12, 55, 225, 10, 257, + 188, 189, 185, 190, 191, 192, 201, 164, 56, 11, + 130, 73, 74, 1, 75, 76, 77, 78, 0, 0, + 58, 0, 58, 89, 90, 91, 95, 115, 0, 81, + 83, 0, 0, 94, 92, 93, 97, 96, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 111, 110, 112, 113, 114, 118, 116, 117, 0, 0, + 0, 60, 61, 0, 62, 63, 64, 65, 167, 170, + 171, 172, 173, 174, 175, 0, 252, 0, 89, 90, + 91, 95, 115, 0, 0, 83, 84, 85, 94, 92, + 93, 97, 96, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 111, 110, 112, 113, 114, + 118, 116, 117, 202, 203, 193, 194, 195, 196, 197, + 198, 200, 199, 245, 0, 0, 0, 0, 0, 0, + 188, 189, 0, 190, 191, 192, 201, 19, 20, 21, + 0, 84, 85, 177, 43, 0, 42, 226, 50, 0, + 44, 45, 47, 48, 49, 52, 51, 0, 0, 0, + 202, 203, 193, 194, 195, 196, 197, 198, 200, 199, + 187, 23, 26, 24, 25, 27, 0, 188, 189, 0, + 190, 191, 192, 201, 202, 203, 193, 194, 195, 196, + 197, 198, 200, 199, 0, 0, 0, 0, 0, 22, + 0, 188, 189, 0, 190, 191, 192, 201, 0, 202, + 203, 193, 194, 195, 196, 197, 198, 200, 199, 0, + 0, 0, 0, 0, 0, 0, 188, 189, 0, 190, + 191, 192, 201, 202, 203, 193, 194, 195, 196, 197, + 198, 200, 199, 166, 0, 0, 0, 0, 0, 0, + 188, 189, 0, 190, 191, 192, 201, 193, 194, 195, + 196, 197, 198, 200, 199, 0, 0, 0, 0, 0, + 0, 0, 188, 189, 0, 190, 191, 192, 201, 0, + 0, 0, 66, 67, 68, 69, 70, 71, 0, 66, + 67, 68, 69, 70, 71, 0, 0, 73, 74, 0, + 75, 76, 77, 78, 60, 61, 0, 62, 63, 64, + 65, 19, 20, 21, 0, 17, 0, 224, 0, 19, + 20, 21, 0, 17, 0, 222, 0, 19, 20, 21, + 31, 17, 30, 9, 40, 0, 32, 33, 35, 36, + 37, 38, 39, 0, 0, 23, 26, 24, 25, 27, + 14, 0, 15, 23, 26, 24, 25, 27, 14, 163, + 15, 23, 26, 24, 25, 27, 14, 0, 15, 0, + 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, + 0, 22, 19, 20, 21, 160, 17, 0, 132, 22, + 0, 0, 0, 0, 0, 0, 41, 46, 0, 0, + 43, 0, 42, 0, 50, 0, 44, 45, 47, 48, + 49, 52, 51, 0, 0, 0, 23, 26, 24, 25, + 27, 0, 29, 34, 0, 0, 31, 0, 30, 0, + 40, 0, 32, 33, 35, 36, 37, 38, 39, 41, + 46, 0, 0, 43, 22, 42, 0, 50, 0, 44, + 45, 47, 48, 49, 52, 51, 29, 34, 53, 3, + 31, 0, 30, 0, 40, 0, 32, 33, 35, 36, + 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 134, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 89, 90, 91, 95, 0, 0, 0, 169, 0, 0, + 94, 92, 93, 97, 96, 98, 99, 100, 101, 102, + 103, 104, } var yyPact = [...]int{ - 538, -1000, -18, 291, -1000, 103, -1000, -1000, -1000, 538, - -1000, 448, -1000, 134, 183, 182, -1000, 228, -1000, -1000, - -1000, -1000, 214, 181, 180, 149, 146, 144, 512, 143, - 143, 143, 143, 143, 143, 143, 133, 133, 133, 133, - 133, 133, 133, 553, 23, 218, 43, 109, 430, 657, - 126, 126, 126, 126, 126, 126, -1000, -1000, -1000, -1000, - -1000, -1000, 588, 588, 588, 588, 588, 588, 588, 279, - 279, -1000, 412, 279, 279, 279, -1000, -1000, -1000, -1000, + 551, -1000, -34, 636, -1000, 619, -1000, -1000, -1000, 551, + -1000, 467, -1000, 40, 154, 153, -1000, 248, -1000, -1000, + -1000, -1000, 167, 149, 142, 136, 121, 120, 139, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 602, 110, 576, 224, 96, 460, 725, + 109, 109, 109, 109, 109, 109, -1000, -1000, -1000, -1000, + -1000, -1000, 361, 361, 361, 361, 361, 361, 361, 303, + 303, -1000, 389, 303, 303, 303, -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, 234, 221, 201, 95, -1000, - -1000, -1000, 100, 279, 279, 279, 279, 103, -1000, -1000, - -1000, -1000, 581, 96, 294, 528, -1000, -1000, -1000, -1000, - 294, -1000, 106, 133, -1000, -1000, -1000, -1000, 106, -1000, - -1000, -1000, 512, -1000, -1000, -1000, -1000, 34, -1000, 520, - 52, 52, -54, -54, -54, -54, -43, 588, 19, 19, - -59, -59, -59, -59, 383, 91, 160, -1000, 279, 279, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 363, 0, 0, 41, 32, 29, - 13, 195, 142, -1000, 336, 316, 269, -4, 218, 15, - 44, 9, 528, -1000, 520, -20, -1000, -1000, 279, 0, - 0, -62, -62, -62, -50, -50, -50, -50, -50, -50, - -50, -50, -62, 73, 73, -1000, -1000, -1000, -1000, -1000, - -3, -16, -1000, -1000, -1000, -1000, -1000, 160, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 205, 204, 202, 124, -1000, + -1000, -1000, 86, 303, 303, 303, 303, 619, -1000, -1000, + -1000, -1000, 606, 104, 506, 543, -1000, -1000, -1000, -1000, + 506, -1000, -1000, -1000, -1000, -1000, -1000, 320, 119, -1000, + -1000, -1000, -1000, 320, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 139, -1000, -1000, -1000, -1000, 47, -1000, 535, + 17, 17, -63, -63, -63, -63, -2, 361, -32, -32, + -64, -64, -64, -64, 364, 69, 413, -1000, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 340, -47, -47, 31, -6, -12, + -16, 184, 173, -1000, 293, 163, 85, 5, 576, 174, + 78, 18, 543, -1000, 535, -36, -1000, -1000, 303, -47, + -47, -65, -65, -65, -51, -51, -51, -51, -51, -51, + -51, -51, -65, 435, 435, -1000, -1000, -1000, -1000, -1000, + -19, -20, -1000, -1000, -1000, -1000, -1000, 413, -1000, -1000, } var yyPgo = [...]int{ - 0, 283, 6, 281, 5, 277, 1, 424, 276, 2, - 275, 4, 196, 273, 605, 27, 271, 270, 8, 0, - 73, 242, 241, + 0, 243, 6, 240, 5, 232, 1, 688, 228, 2, + 225, 4, 211, 212, 238, 27, 210, 178, 7, 0, + 14, 171, 122, } var yyR1 = [...]int{ 0, 1, 1, 1, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 8, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 2, 3, 4, 5, 5, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 2, 3, + 4, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 11, 12, 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 16, 17, 15, 15, @@ -330,8 +348,9 @@ var yyR1 = [...]int{ var yyR2 = [...]int{ 0, 1, 1, 1, 3, 3, 3, 3, 3, 3, - 3, 3, 1, 3, 1, 1, 1, 1, 3, 3, - 3, 3, 3, 4, 3, 4, 1, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 1, 3, 1, + 1, 1, 1, 3, 3, 3, 3, 3, 4, 3, + 4, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 2, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, @@ -348,23 +367,25 @@ var yyChk = [...]int{ -1000, -1, -9, -7, -13, -6, -11, -2, -4, 12, -8, -14, -10, -15, 45, 47, -16, 10, -18, 6, - 7, 8, 64, 40, 42, 43, 41, 44, 49, 50, - 56, 54, 60, 61, 51, 62, 50, 56, 54, 60, - 61, 51, 62, -7, -9, -6, -14, -17, -15, -12, - 63, 64, 66, 67, 68, 69, 52, 53, 54, 55, - 56, 57, -12, 63, 64, 66, 67, 68, 69, 12, - 12, 11, -19, 12, 64, 65, -20, -21, -22, 5, + 7, 8, 68, 40, 42, 43, 41, 44, 49, 50, + 56, 54, 60, 61, 51, 62, 63, 64, 65, 66, + 58, 50, 56, 54, 60, 61, 51, 62, 63, 64, + 58, 66, 65, -7, -9, -6, -14, -17, -15, -12, + 67, 68, 70, 71, 72, 73, 52, 53, 54, 55, + 56, 57, -12, 67, 68, 70, 71, 72, 73, 12, + 12, 11, -19, 12, 68, 69, -20, -21, -22, 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, 36, 9, 38, 39, 37, 6, 7, 8, 12, 12, 12, 12, 12, -6, -11, -2, -3, -4, 12, 46, -7, 12, -7, -7, -7, -7, - -7, -7, -6, 12, -6, -6, -6, -6, -6, -6, + -7, -7, -7, -7, -7, -7, -7, -6, 12, -6, + -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, 13, 13, 49, 13, 13, 13, 13, -14, -20, 12, -14, -14, -14, -14, -14, -14, -15, 12, -15, -15, - -15, -15, -15, -15, -19, -5, -19, 11, 63, 64, - 66, 67, 68, 52, 53, 54, 55, 56, 57, 59, - 58, 69, 50, 51, -19, -19, -19, 4, 4, 4, + -15, -15, -15, -15, -19, -5, -19, 11, 67, 68, + 70, 71, 72, 52, 53, 54, 55, 56, 57, 59, + 58, 73, 50, 51, -19, -19, -19, 4, 4, 4, 4, 38, 39, 13, -19, -19, -19, -19, -6, -15, 12, -9, 12, -18, 12, -9, 13, 13, 14, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, @@ -373,30 +394,32 @@ var yyChk = [...]int{ } var yyDef = [...]int{ - 0, -2, 1, 2, 3, 14, 15, 16, 17, 0, - 12, 0, 36, 0, 0, 0, 55, 0, 65, 66, - 67, 68, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, 1, 2, 3, 19, 20, 21, 22, 0, + 17, 0, 46, 0, 0, 0, 65, 0, 75, 76, + 77, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 40, 41, 42, 43, - 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 37, 0, 0, 0, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 51, 52, 53, + 54, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 0, 0, 0, 0, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 0, 0, 0, 0, 69, - 70, 71, 0, 0, 0, 0, 0, 18, 19, 20, - 21, 22, 0, 0, 5, 0, 6, 7, 8, 9, - 10, 11, 29, 0, 30, 31, 32, 33, 34, 35, - 4, 13, 0, 28, 48, 56, 58, 46, 47, 0, - 49, 50, 51, 52, 53, 54, 39, 0, 59, 60, - 61, 62, 63, 64, 0, 0, 26, 38, 0, 0, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 0, 0, 0, 0, 79, + 80, 81, 0, 0, 0, 0, 0, 23, 24, 25, + 26, 27, 0, 0, 5, 0, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 34, 0, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 4, 18, 0, 33, 58, 66, 68, 56, 57, 0, + 59, 60, 61, 62, 63, 64, 49, 0, 69, 70, + 71, 72, 73, 74, 0, 0, 31, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 94, 95, 0, 0, 0, - 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -2, 0, 0, 23, 25, 0, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 77, 125, 126, 127, 128, - 0, 0, 73, 74, 75, 76, 24, 27, 129, 130, + 0, 0, 0, 0, 0, 104, 105, 0, 0, 0, + 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -2, 0, 0, 28, 30, 0, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 87, 135, 136, 137, 138, + 0, 0, 83, 84, 85, 86, 29, 32, 139, 140, } var yyTok1 = [...]int{ @@ -410,7 +433,8 @@ var yyTok2 = [...]int{ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, } var yyTok3 = [...]int{ 0, @@ -820,716 +844,776 @@ yydefault: yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetSibling, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) } case 12: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line pkg/traceql/expr.y:115 { - yyVAL.spansetPipelineExpression = yyDollar[1].wrappedSpansetPipeline + yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetNotChild, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) } case 13: yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:116 + { + yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetNotParent, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) + } + case 14: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:117 + { + yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetNotDescendant, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) + } + case 15: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:118 + { + yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetNotAncestor, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) + } + case 16: + yyDollar = yyS[yypt-3 : yypt+1] //line pkg/traceql/expr.y:119 + { + yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetNotSibling, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) + } + case 17: + yyDollar = yyS[yypt-1 : yypt+1] +//line pkg/traceql/expr.y:120 + { + yyVAL.spansetPipelineExpression = yyDollar[1].wrappedSpansetPipeline + } + case 18: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:124 { yyVAL.wrappedSpansetPipeline = yyDollar[2].spansetPipeline } - case 14: + case 19: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:122 +//line pkg/traceql/expr.y:127 { yyVAL.spansetPipeline = newPipeline(yyDollar[1].spansetExpression) } - case 15: + case 20: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:123 +//line pkg/traceql/expr.y:128 { yyVAL.spansetPipeline = newPipeline(yyDollar[1].scalarFilter) } - case 16: + case 21: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:124 +//line pkg/traceql/expr.y:129 { yyVAL.spansetPipeline = newPipeline(yyDollar[1].groupOperation) } - case 17: + case 22: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:125 +//line pkg/traceql/expr.y:130 { yyVAL.spansetPipeline = newPipeline(yyDollar[1].selectOperation) } - case 18: + case 23: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:126 +//line pkg/traceql/expr.y:131 { yyVAL.spansetPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].spansetExpression) } - case 19: + case 24: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:127 +//line pkg/traceql/expr.y:132 { yyVAL.spansetPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].scalarFilter) } - case 20: + case 25: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:128 +//line pkg/traceql/expr.y:133 { yyVAL.spansetPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].groupOperation) } - case 21: + case 26: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:129 +//line pkg/traceql/expr.y:134 { yyVAL.spansetPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].coalesceOperation) } - case 22: + case 27: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:130 +//line pkg/traceql/expr.y:135 { yyVAL.spansetPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].selectOperation) } - case 23: + case 28: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:134 +//line pkg/traceql/expr.y:139 { yyVAL.groupOperation = newGroupOperation(yyDollar[3].fieldExpression) } - case 24: + case 29: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:138 +//line pkg/traceql/expr.y:143 { yyVAL.coalesceOperation = newCoalesceOperation() } - case 25: + case 30: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:142 +//line pkg/traceql/expr.y:147 { yyVAL.selectOperation = newSelectOperation(yyDollar[3].selectArgs) } - case 26: + case 31: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:146 +//line pkg/traceql/expr.y:151 { yyVAL.selectArgs = []FieldExpression{yyDollar[1].fieldExpression} } - case 27: + case 32: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:147 +//line pkg/traceql/expr.y:152 { yyVAL.selectArgs = append(yyDollar[1].selectArgs, yyDollar[3].fieldExpression) } - case 28: + case 33: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:151 +//line pkg/traceql/expr.y:156 { yyVAL.spansetExpression = yyDollar[2].spansetExpression } - case 29: + case 34: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:152 +//line pkg/traceql/expr.y:157 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetAnd, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 30: + case 35: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:153 +//line pkg/traceql/expr.y:158 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetChild, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 31: + case 36: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:154 +//line pkg/traceql/expr.y:159 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetParent, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 32: + case 37: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:155 +//line pkg/traceql/expr.y:160 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetDescendant, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 33: + case 38: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:156 +//line pkg/traceql/expr.y:161 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetAncestor, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 34: + case 39: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:157 +//line pkg/traceql/expr.y:162 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetUnion, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 35: + case 40: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:158 +//line pkg/traceql/expr.y:163 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetSibling, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 36: + case 41: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:165 + { + yyVAL.spansetExpression = newSpansetOperation(OpSpansetNotChild, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) + } + case 42: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:166 + { + yyVAL.spansetExpression = newSpansetOperation(OpSpansetNotParent, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) + } + case 43: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:167 + { + yyVAL.spansetExpression = newSpansetOperation(OpSpansetNotSibling, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) + } + case 44: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:168 + { + yyVAL.spansetExpression = newSpansetOperation(OpSpansetNotAncestor, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) + } + case 45: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:169 + { + yyVAL.spansetExpression = newSpansetOperation(OpSpansetNotDescendant, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) + } + case 46: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:159 +//line pkg/traceql/expr.y:171 { yyVAL.spansetExpression = yyDollar[1].spansetFilter } - case 37: + case 47: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:163 +//line pkg/traceql/expr.y:175 { yyVAL.spansetFilter = newSpansetFilter(NewStaticBool(true)) } - case 38: + case 48: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:164 +//line pkg/traceql/expr.y:176 { yyVAL.spansetFilter = newSpansetFilter(yyDollar[2].fieldExpression) } - case 39: + case 49: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:168 +//line pkg/traceql/expr.y:180 { yyVAL.scalarFilter = newScalarFilter(yyDollar[2].scalarFilterOperation, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 40: + case 50: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:172 +//line pkg/traceql/expr.y:184 { yyVAL.scalarFilterOperation = OpEqual } - case 41: + case 51: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:173 +//line pkg/traceql/expr.y:185 { yyVAL.scalarFilterOperation = OpNotEqual } - case 42: + case 52: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:174 +//line pkg/traceql/expr.y:186 { yyVAL.scalarFilterOperation = OpLess } - case 43: + case 53: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:175 +//line pkg/traceql/expr.y:187 { yyVAL.scalarFilterOperation = OpLessEqual } - case 44: + case 54: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:176 +//line pkg/traceql/expr.y:188 { yyVAL.scalarFilterOperation = OpGreater } - case 45: + case 55: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:177 +//line pkg/traceql/expr.y:189 { yyVAL.scalarFilterOperation = OpGreaterEqual } - case 46: + case 56: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:184 +//line pkg/traceql/expr.y:196 { yyVAL.scalarPipelineExpressionFilter = newScalarFilter(yyDollar[2].scalarFilterOperation, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 47: + case 57: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:185 +//line pkg/traceql/expr.y:197 { yyVAL.scalarPipelineExpressionFilter = newScalarFilter(yyDollar[2].scalarFilterOperation, yyDollar[1].scalarPipelineExpression, yyDollar[3].static) } - case 48: + case 58: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:189 +//line pkg/traceql/expr.y:201 { yyVAL.scalarPipelineExpression = yyDollar[2].scalarPipelineExpression } - case 49: + case 59: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:190 +//line pkg/traceql/expr.y:202 { yyVAL.scalarPipelineExpression = newScalarOperation(OpAdd, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 50: + case 60: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:191 +//line pkg/traceql/expr.y:203 { yyVAL.scalarPipelineExpression = newScalarOperation(OpSub, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 51: + case 61: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:192 +//line pkg/traceql/expr.y:204 { yyVAL.scalarPipelineExpression = newScalarOperation(OpMult, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 52: + case 62: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:193 +//line pkg/traceql/expr.y:205 { yyVAL.scalarPipelineExpression = newScalarOperation(OpDiv, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 53: + case 63: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:194 +//line pkg/traceql/expr.y:206 { yyVAL.scalarPipelineExpression = newScalarOperation(OpMod, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 54: + case 64: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:195 +//line pkg/traceql/expr.y:207 { yyVAL.scalarPipelineExpression = newScalarOperation(OpPower, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 55: + case 65: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:196 +//line pkg/traceql/expr.y:208 { yyVAL.scalarPipelineExpression = yyDollar[1].wrappedScalarPipeline } - case 56: + case 66: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:200 +//line pkg/traceql/expr.y:212 { yyVAL.wrappedScalarPipeline = yyDollar[2].scalarPipeline } - case 57: + case 67: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:204 +//line pkg/traceql/expr.y:216 { yyVAL.scalarPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].aggregate) } - case 58: + case 68: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:208 +//line pkg/traceql/expr.y:220 { yyVAL.scalarExpression = yyDollar[2].scalarExpression } - case 59: + case 69: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:209 +//line pkg/traceql/expr.y:221 { yyVAL.scalarExpression = newScalarOperation(OpAdd, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 60: + case 70: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:210 +//line pkg/traceql/expr.y:222 { yyVAL.scalarExpression = newScalarOperation(OpSub, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 61: + case 71: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:211 +//line pkg/traceql/expr.y:223 { yyVAL.scalarExpression = newScalarOperation(OpMult, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 62: + case 72: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:212 +//line pkg/traceql/expr.y:224 { yyVAL.scalarExpression = newScalarOperation(OpDiv, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 63: + case 73: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:213 +//line pkg/traceql/expr.y:225 { yyVAL.scalarExpression = newScalarOperation(OpMod, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 64: + case 74: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:214 +//line pkg/traceql/expr.y:226 { yyVAL.scalarExpression = newScalarOperation(OpPower, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 65: + case 75: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:215 +//line pkg/traceql/expr.y:227 { yyVAL.scalarExpression = yyDollar[1].aggregate } - case 66: + case 76: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:216 +//line pkg/traceql/expr.y:228 { yyVAL.scalarExpression = NewStaticInt(yyDollar[1].staticInt) } - case 67: + case 77: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:217 +//line pkg/traceql/expr.y:229 { yyVAL.scalarExpression = NewStaticFloat(yyDollar[1].staticFloat) } - case 68: + case 78: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:218 +//line pkg/traceql/expr.y:230 { yyVAL.scalarExpression = NewStaticDuration(yyDollar[1].staticDuration) } - case 69: + case 79: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:219 +//line pkg/traceql/expr.y:231 { yyVAL.scalarExpression = NewStaticInt(-yyDollar[2].staticInt) } - case 70: + case 80: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:220 +//line pkg/traceql/expr.y:232 { yyVAL.scalarExpression = NewStaticFloat(-yyDollar[2].staticFloat) } - case 71: + case 81: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:221 +//line pkg/traceql/expr.y:233 { yyVAL.scalarExpression = NewStaticDuration(-yyDollar[2].staticDuration) } - case 72: + case 82: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:225 +//line pkg/traceql/expr.y:237 { yyVAL.aggregate = newAggregate(aggregateCount, nil) } - case 73: + case 83: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:226 +//line pkg/traceql/expr.y:238 { yyVAL.aggregate = newAggregate(aggregateMax, yyDollar[3].fieldExpression) } - case 74: + case 84: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:227 +//line pkg/traceql/expr.y:239 { yyVAL.aggregate = newAggregate(aggregateMin, yyDollar[3].fieldExpression) } - case 75: + case 85: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:228 +//line pkg/traceql/expr.y:240 { yyVAL.aggregate = newAggregate(aggregateAvg, yyDollar[3].fieldExpression) } - case 76: + case 86: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:229 +//line pkg/traceql/expr.y:241 { yyVAL.aggregate = newAggregate(aggregateSum, yyDollar[3].fieldExpression) } - case 77: + case 87: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:236 +//line pkg/traceql/expr.y:248 { yyVAL.fieldExpression = yyDollar[2].fieldExpression } - case 78: + case 88: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:237 +//line pkg/traceql/expr.y:249 { yyVAL.fieldExpression = newBinaryOperation(OpAdd, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 79: + case 89: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:238 +//line pkg/traceql/expr.y:250 { yyVAL.fieldExpression = newBinaryOperation(OpSub, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 80: + case 90: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:239 +//line pkg/traceql/expr.y:251 { yyVAL.fieldExpression = newBinaryOperation(OpMult, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 81: + case 91: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:240 +//line pkg/traceql/expr.y:252 { yyVAL.fieldExpression = newBinaryOperation(OpDiv, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 82: + case 92: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:241 +//line pkg/traceql/expr.y:253 { yyVAL.fieldExpression = newBinaryOperation(OpMod, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 83: + case 93: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:242 +//line pkg/traceql/expr.y:254 { yyVAL.fieldExpression = newBinaryOperation(OpEqual, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 84: + case 94: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:243 +//line pkg/traceql/expr.y:255 { yyVAL.fieldExpression = newBinaryOperation(OpNotEqual, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 85: + case 95: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:244 +//line pkg/traceql/expr.y:256 { yyVAL.fieldExpression = newBinaryOperation(OpLess, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 86: + case 96: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:245 +//line pkg/traceql/expr.y:257 { yyVAL.fieldExpression = newBinaryOperation(OpLessEqual, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 87: + case 97: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:246 +//line pkg/traceql/expr.y:258 { yyVAL.fieldExpression = newBinaryOperation(OpGreater, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 88: + case 98: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:247 +//line pkg/traceql/expr.y:259 { yyVAL.fieldExpression = newBinaryOperation(OpGreaterEqual, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 89: + case 99: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:248 +//line pkg/traceql/expr.y:260 { yyVAL.fieldExpression = newBinaryOperation(OpRegex, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 90: + case 100: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:249 +//line pkg/traceql/expr.y:261 { yyVAL.fieldExpression = newBinaryOperation(OpNotRegex, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 91: + case 101: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:250 +//line pkg/traceql/expr.y:262 { yyVAL.fieldExpression = newBinaryOperation(OpPower, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 92: + case 102: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:251 +//line pkg/traceql/expr.y:263 { yyVAL.fieldExpression = newBinaryOperation(OpAnd, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 93: + case 103: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:252 +//line pkg/traceql/expr.y:264 { yyVAL.fieldExpression = newBinaryOperation(OpOr, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 94: + case 104: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:253 +//line pkg/traceql/expr.y:265 { yyVAL.fieldExpression = newUnaryOperation(OpSub, yyDollar[2].fieldExpression) } - case 95: + case 105: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:254 +//line pkg/traceql/expr.y:266 { yyVAL.fieldExpression = newUnaryOperation(OpNot, yyDollar[2].fieldExpression) } - case 96: + case 106: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:255 +//line pkg/traceql/expr.y:267 { yyVAL.fieldExpression = yyDollar[1].static } - case 97: + case 107: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:256 +//line pkg/traceql/expr.y:268 { yyVAL.fieldExpression = yyDollar[1].intrinsicField } - case 98: + case 108: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:257 +//line pkg/traceql/expr.y:269 { yyVAL.fieldExpression = yyDollar[1].attributeField } - case 99: + case 109: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:264 +//line pkg/traceql/expr.y:276 { yyVAL.static = NewStaticString(yyDollar[1].staticStr) } - case 100: + case 110: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:265 +//line pkg/traceql/expr.y:277 { yyVAL.static = NewStaticInt(yyDollar[1].staticInt) } - case 101: + case 111: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:266 +//line pkg/traceql/expr.y:278 { yyVAL.static = NewStaticFloat(yyDollar[1].staticFloat) } - case 102: + case 112: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:267 +//line pkg/traceql/expr.y:279 { yyVAL.static = NewStaticBool(true) } - case 103: + case 113: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:268 +//line pkg/traceql/expr.y:280 { yyVAL.static = NewStaticBool(false) } - case 104: + case 114: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:269 +//line pkg/traceql/expr.y:281 { yyVAL.static = NewStaticNil() } - case 105: + case 115: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:270 +//line pkg/traceql/expr.y:282 { yyVAL.static = NewStaticDuration(yyDollar[1].staticDuration) } - case 106: + case 116: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:271 +//line pkg/traceql/expr.y:283 { yyVAL.static = NewStaticStatus(StatusOk) } - case 107: + case 117: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:272 +//line pkg/traceql/expr.y:284 { yyVAL.static = NewStaticStatus(StatusError) } - case 108: + case 118: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:273 +//line pkg/traceql/expr.y:285 { yyVAL.static = NewStaticStatus(StatusUnset) } - case 109: + case 119: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:274 +//line pkg/traceql/expr.y:286 { yyVAL.static = NewStaticKind(KindUnspecified) } - case 110: + case 120: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:275 +//line pkg/traceql/expr.y:287 { yyVAL.static = NewStaticKind(KindInternal) } - case 111: + case 121: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:276 +//line pkg/traceql/expr.y:288 { yyVAL.static = NewStaticKind(KindServer) } - case 112: + case 122: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:277 +//line pkg/traceql/expr.y:289 { yyVAL.static = NewStaticKind(KindClient) } - case 113: + case 123: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:278 +//line pkg/traceql/expr.y:290 { yyVAL.static = NewStaticKind(KindProducer) } - case 114: + case 124: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:279 +//line pkg/traceql/expr.y:291 { yyVAL.static = NewStaticKind(KindConsumer) } - case 115: + case 125: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:283 +//line pkg/traceql/expr.y:295 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicDuration) } - case 116: + case 126: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:284 +//line pkg/traceql/expr.y:296 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicChildCount) } - case 117: + case 127: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:285 +//line pkg/traceql/expr.y:297 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicName) } - case 118: + case 128: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:286 +//line pkg/traceql/expr.y:298 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicStatus) } - case 119: + case 129: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:287 +//line pkg/traceql/expr.y:299 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicStatusMessage) } - case 120: + case 130: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:288 +//line pkg/traceql/expr.y:300 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicKind) } - case 121: + case 131: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:289 +//line pkg/traceql/expr.y:301 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicParent) } - case 122: + case 132: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:290 +//line pkg/traceql/expr.y:302 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicTraceRootSpan) } - case 123: + case 133: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:291 +//line pkg/traceql/expr.y:303 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicTraceRootService) } - case 124: + case 134: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:292 +//line pkg/traceql/expr.y:304 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicTraceDuration) } - case 125: + case 135: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:296 +//line pkg/traceql/expr.y:308 { yyVAL.attributeField = NewAttribute(yyDollar[2].staticStr) } - case 126: + case 136: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:297 +//line pkg/traceql/expr.y:309 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, false, yyDollar[2].staticStr) } - case 127: + case 137: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:298 +//line pkg/traceql/expr.y:310 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, false, yyDollar[2].staticStr) } - case 128: + case 138: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:299 +//line pkg/traceql/expr.y:311 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeNone, true, yyDollar[2].staticStr) } - case 129: + case 139: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:300 +//line pkg/traceql/expr.y:312 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, true, yyDollar[3].staticStr) } - case 130: + case 140: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:301 +//line pkg/traceql/expr.y:313 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, true, yyDollar[3].staticStr) } diff --git a/pkg/traceql/lexer.go b/pkg/traceql/lexer.go index 6fac53b30ac..fe50ac88818 100644 --- a/pkg/traceql/lexer.go +++ b/pkg/traceql/lexer.go @@ -20,7 +20,7 @@ var tokens = map[string]int{ "=": EQ, "!=": NEQ, "=~": RE, - "!~": NRE, + "!~": NRE, // also "not sibling" ">": GT, ">=": GTE, "<": LT, @@ -49,7 +49,11 @@ var tokens = map[string]int{ "|": PIPE, ">>": DESC, "<<": ANCE, - "~": TILDE, + "~": SIBL, + "!>": NOT_CHILD, + "!<": NOT_PARENT, + "!>>": NOT_DESC, + "!<<": NOT_ANCE, "duration": IDURATION, "childCount": CHILDCOUNT, "name": NAME, @@ -167,18 +171,36 @@ func (l *lexer) Lex(lval *yySymType) int { return FLOAT } - tokStrNext := l.TokenText() + string(l.Peek()) - if tok, ok := tokens[tokStrNext]; ok { - l.Next() - l.parsingAttribute = startsAttribute(tok) - return tok + // 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 + multiTok := -1 + tokStrNext := l.TokenText() + for { + tokStrNext = tokStrNext + string(l.Peek()) + tok, ok := tokens[tokStrNext] + if ok { + multiTok = tok + l.Next() + continue + } + + break + } + + // did we find a combination token? + if multiTok != -1 { + l.parsingAttribute = startsAttribute(multiTok) + return multiTok } + // no combination tokens, see if the current text is a known token if tok, ok := tokens[l.TokenText()]; ok { l.parsingAttribute = startsAttribute(tok) return tok } + // default to an identifier lval.staticStr = l.TokenText() return IDENTIFIER } diff --git a/pkg/traceql/lexer_test.go b/pkg/traceql/lexer_test.go index 401fa1229bc..1ff75b3c289 100644 --- a/pkg/traceql/lexer_test.go +++ b/pkg/traceql/lexer_test.go @@ -66,6 +66,17 @@ func TestLexerAttributes(t *testing.T) { })) } +func TestLexerMultitokens(t *testing.T) { + testLexer(t, ([]lexerTestCase{ + // attributes + {`&&`, []int{AND}}, + {`>>`, []int{DESC}}, + {`!<<`, []int{NOT_ANCE}}, + {`!`, []int{NOT}}, + {`!~`, []int{NRE}}, + })) +} + func TestLexerDuration(t *testing.T) { testLexer(t, ([]lexerTestCase{ // duration @@ -131,6 +142,7 @@ func testLexer(t *testing.T, tcs []lexerTestCase) { } actual = append(actual, tok) } + require.Equal(t, tc.expected, actual) }) } diff --git a/pkg/traceql/parse_test.go b/pkg/traceql/parse_test.go index 1d96bd10a46..dd5f60e01a3 100644 --- a/pkg/traceql/parse_test.go +++ b/pkg/traceql/parse_test.go @@ -133,6 +133,19 @@ func TestPipelineSpansetOperators(t *testing.T) { ), ), }, + { + in: "({ .a } | { .b }) ~ ({ .a } | { .b })", + expected: newSpansetOperation(OpSpansetSibling, + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + ), + }, { in: "({ .a } | { .b }) && ({ .a } | { .b })", expected: newSpansetOperation(OpSpansetAnd, @@ -172,6 +185,71 @@ func TestPipelineSpansetOperators(t *testing.T) { ), ), }, + { + in: "({ .a } | { .b }) !> ({ .a } | { .b })", + expected: newSpansetOperation(OpSpansetNotChild, + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + ), + }, + { + in: "({ .a } | { .b }) !< ({ .a } | { .b })", + expected: newSpansetOperation(OpSpansetNotParent, + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + ), + }, + { + in: "({ .a } | { .b }) !~ ({ .a } | { .b })", + expected: newSpansetOperation(OpSpansetNotSibling, + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + ), + }, + { + in: "({ .a } | { .b }) !>> ({ .a } | { .b })", + expected: newSpansetOperation(OpSpansetNotDescendant, + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + ), + }, + { + in: "({ .a } | { .b }) !<< ({ .a } | { .b })", + expected: newSpansetOperation(OpSpansetNotAncestor, + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + newPipeline( + newSpansetFilter(NewAttribute("a")), + newSpansetFilter(NewAttribute("b")), + ), + ), + }, } for _, tc := range tests { @@ -464,6 +542,11 @@ func TestSpansetExpressionOperators(t *testing.T) { {in: "{ true } ~ { false }", expected: newSpansetOperation(OpSpansetSibling, newSpansetFilter(NewStaticBool(true)), newSpansetFilter(NewStaticBool(false)))}, // this test was added to highlight the one shift/reduce conflict in the grammar. this could also be parsed as two spanset pipelines &&ed together. {in: "({ true }) && ({ false })", expected: newSpansetOperation(OpSpansetAnd, newSpansetFilter(NewStaticBool(true)), newSpansetFilter(NewStaticBool(false)))}, + {in: "{ true } !> { false }", expected: newSpansetOperation(OpSpansetNotChild, newSpansetFilter(NewStaticBool(true)), newSpansetFilter(NewStaticBool(false)))}, + {in: "{ true } !< { false }", expected: newSpansetOperation(OpSpansetNotParent, newSpansetFilter(NewStaticBool(true)), newSpansetFilter(NewStaticBool(false)))}, + {in: "{ true } !>> { false }", expected: newSpansetOperation(OpSpansetNotDescendant, newSpansetFilter(NewStaticBool(true)), newSpansetFilter(NewStaticBool(false)))}, + {in: "{ true } !<< { false }", expected: newSpansetOperation(OpSpansetNotAncestor, newSpansetFilter(NewStaticBool(true)), newSpansetFilter(NewStaticBool(false)))}, + {in: "{ true } !~ { false }", expected: newSpansetOperation(OpSpansetNotSibling, newSpansetFilter(NewStaticBool(true)), newSpansetFilter(NewStaticBool(false)))}, } for _, tc := range tests { diff --git a/pkg/traceql/test_examples.yaml b/pkg/traceql/test_examples.yaml index befe23ec6cc..a71c5c80dab 100644 --- a/pkg/traceql/test_examples.yaml +++ b/pkg/traceql/test_examples.yaml @@ -74,6 +74,11 @@ valid: - '{ true } > { true }' - '{ true } < { true }' - '{ true } ~ { true }' + - '{ true } !> { true }' + - '{ true } !< { true }' + - '{ true } !~ { true }' + - '{ true } !>> { true }' + - '{ true } !<< { true }' - '({ true } | count() > 1 | { false }) >> ({ true } | count() > 1 | { false })' - '({ true } | count() > 1 | { false }) > ({ true } | count() > 1 | { false })' - '({ true } | count() > 1 | { false }) ~ ({ true } | count() > 1 | { false })' diff --git a/tempodb/tempodb_search_test.go b/tempodb/tempodb_search_test.go index a66d0e0b459..2934fb20960 100644 --- a/tempodb/tempodb_search_test.go +++ b/tempodb/tempodb_search_test.go @@ -517,6 +517,116 @@ func traceQLStructural(t *testing.T, _ *tempopb.Trace, wantMeta *tempopb.TraceSe }, }, }, + { + req: &tempopb.SearchRequest{Query: "{ .child } !> { .parent }"}, + expected: []*tempopb.TraceSearchMetadata{ + { + SpanSets: []*tempopb.SpanSet{ + { + Spans: []*tempopb.Span{ + { + SpanID: "0000000000040506", + StartTimeUnixNano: 1000000000000, + DurationNanos: 2000000000, + Attributes: []*v1_common.KeyValue{ + {Key: "parent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_BoolValue{BoolValue: true}}}, + }, + }, + }, + Matched: 1, + }, + }, + }, + }, + }, + { + req: &tempopb.SearchRequest{Query: "{ .child } !>> { .parent }"}, + expected: []*tempopb.TraceSearchMetadata{ + { + SpanSets: []*tempopb.SpanSet{ + { + Spans: []*tempopb.Span{ + { + SpanID: "0000000000040506", + StartTimeUnixNano: 1000000000000, + DurationNanos: 2000000000, + Attributes: []*v1_common.KeyValue{ + {Key: "parent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_BoolValue{BoolValue: true}}}, + }, + }, + }, + Matched: 1, + }, + }, + }, + }, + }, + { + req: &tempopb.SearchRequest{Query: "{ .child } !~ { .parent }"}, + expected: []*tempopb.TraceSearchMetadata{ + { + SpanSets: []*tempopb.SpanSet{ + { + Spans: []*tempopb.Span{ + { + SpanID: "0000000000040506", + StartTimeUnixNano: 1000000000000, + DurationNanos: 2000000000, + Attributes: []*v1_common.KeyValue{ + {Key: "parent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_BoolValue{BoolValue: true}}}, + }, + }, + }, + Matched: 1, + }, + }, + }, + }, + }, + { + req: &tempopb.SearchRequest{Query: "{ .parent } !< { .child }"}, + expected: []*tempopb.TraceSearchMetadata{ + { + SpanSets: []*tempopb.SpanSet{ + { + Spans: []*tempopb.Span{ + { + SpanID: "0000000000010203", + StartTimeUnixNano: 1000000000000, + DurationNanos: 1000000000, + Attributes: []*v1_common.KeyValue{ + {Key: "child", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_BoolValue{BoolValue: true}}}, + }, + }, + }, + Matched: 1, + }, + }, + }, + }, + }, + { + req: &tempopb.SearchRequest{Query: "{ .parent } !<< { .child }"}, + expected: []*tempopb.TraceSearchMetadata{ + { + SpanSets: []*tempopb.SpanSet{ + { + Spans: []*tempopb.Span{ + { + SpanID: "0000000000010203", + StartTimeUnixNano: 1000000000000, + DurationNanos: 1000000000, + Attributes: []*v1_common.KeyValue{ + {Key: "child", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_BoolValue{BoolValue: true}}}, + }, + }, + }, + Matched: 1, + }, + }, + }, + }, + }, { req: &tempopb.SearchRequest{Query: "{ .child } ~ { .child2 }"}, expected: []*tempopb.TraceSearchMetadata{ @@ -576,6 +686,9 @@ func traceQLStructural(t *testing.T, _ *tempopb.Trace, wantMeta *tempopb.TraceSe {Query: "{} >> {.broken}"}, {Query: "{} > {.broken}"}, {Query: "{} ~ {.broken}"}, + {Query: "{ .child } !< { .parent }"}, + {Query: "{ .parent } !> { .child }"}, + {Query: "{ .child } !~ { .child2 }"}, } for _, tc := range searchesThatMatch {