diff --git a/CHANGELOG.md b/CHANGELOG.md index 27c026560e9..dedf4742677 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ To make use of filtering, configure `autocomplete_filtering_enabled`. * [FEATURE] Add support for `by()` and `coalesce()` to TraceQL. [#2490](https://github.com/grafana/tempo/pull/2490) * [FEATURE] Add a GRPC streaming endpoint for traceql search [#2366](https://github.com/grafana/tempo/pull/2366) (@joe-elliott) * [FEATURE] Add new API to summarize span metrics from generators [#2481](https://github.com/grafana/tempo/pull/2481) (@zalegrala) +* [FEATURE] Add `select()` to TraceQL [#2494](https://github.com/grafana/tempo/pull/2494) (@joe-elliott) * [ENHANCEMENT] Add `scope` parameter to `/api/search/tags` [#2282](https://github.com/grafana/tempo/pull/2282) (@joe-elliott) Create new endpoint `/api/v2/search/tags` that returns all tags organized by scope. * [ENHANCEMENT] Ability to toggle off latency or count metrics in metrics-generator [#2070](https://github.com/grafana/tempo/pull/2070) (@AlexDHoffer) diff --git a/docs/sources/tempo/traceql/_index.md b/docs/sources/tempo/traceql/_index.md index 19153fad98b..6ba1fedc149 100644 --- a/docs/sources/tempo/traceql/_index.md +++ b/docs/sources/tempo/traceql/_index.md @@ -237,6 +237,14 @@ to compare the ratios of two span attributes: ``` or anything else that comes to mind. +## Selection + +TraceQL can select arbitrary fields from spans. This is particularly performant b/c +the selected fields are not retrieved until all other criteria is met. +``` +{ status=error } | select(span.http.status_code, span.http.url) +``` + ## Examples ### Find traces of a specific operation diff --git a/pkg/traceql/ast.go b/pkg/traceql/ast.go index 88a11e7050f..ac49bf3b545 100644 --- a/pkg/traceql/ast.go +++ b/pkg/traceql/ast.go @@ -129,6 +129,16 @@ func newCoalesceOperation() CoalesceOperation { func (o CoalesceOperation) extractConditions(request *FetchSpansRequest) { } +type SelectOperation struct { + exprs []FieldExpression +} + +func newSelectOperation(exprs []FieldExpression) SelectOperation { + return SelectOperation{ + exprs: exprs, + } +} + // ********************** // Scalars // ********************** diff --git a/pkg/traceql/ast_conditions.go b/pkg/traceql/ast_conditions.go index 928fb7cb823..037db81c488 100644 --- a/pkg/traceql/ast_conditions.go +++ b/pkg/traceql/ast_conditions.go @@ -4,6 +4,16 @@ func (f SpansetFilter) extractConditions(request *FetchSpansRequest) { f.Expression.extractConditions(request) } +// extractConditions on Select puts its conditions into the SecondPassConditions +func (o SelectOperation) extractConditions(request *FetchSpansRequest) { + selectR := &FetchSpansRequest{} + for _, expr := range o.exprs { + expr.extractConditions(selectR) + } + // copy any conditions to the normal request's SecondPassConditions + request.SecondPassConditions = append(request.SecondPassConditions, selectR.Conditions...) +} + func (o BinaryOperation) extractConditions(request *FetchSpansRequest) { // TODO we can further optimise this by attempting to execute every FieldExpression, if they only contain statics it should resolve switch o.LHS.(type) { diff --git a/pkg/traceql/ast_conditions_test.go b/pkg/traceql/ast_conditions_test.go index 1302d4829d1..557adf207ac 100644 --- a/pkg/traceql/ast_conditions_test.go +++ b/pkg/traceql/ast_conditions_test.go @@ -104,6 +104,7 @@ func TestSpansetFilter_extractConditions(t *testing.T) { spansetFilter.extractConditions(req) assert.Equal(t, tt.conditions, req.Conditions) + assert.Nil(t, req.SecondPassConditions) assert.Equal(t, tt.allConditions, req.AllConditions, "FetchSpansRequest.AllConditions") }) } @@ -143,6 +144,52 @@ func TestScalarFilter_extractConditions(t *testing.T) { expr.Pipeline.extractConditions(req) assert.Equal(t, tt.conditions, req.Conditions) + assert.Nil(t, req.SecondPassConditions) + assert.Equal(t, tt.allConditions, req.AllConditions, "FetchSpansRequest.AllConditions") + }) + } +} + +func TestSelect_extractConditions(t *testing.T) { + tests := []struct { + query string + conditions []Condition + secondPassConditions []Condition + allConditions bool + }{ + { + query: `{ .foo = "a" } | select(resource.service.name)`, + conditions: []Condition{ + newCondition(NewAttribute("foo"), OpEqual, NewStaticString("a")), + }, + secondPassConditions: []Condition{ + newCondition(NewScopedAttribute(AttributeScopeResource, false, "service.name"), OpNone), + }, + allConditions: false, + }, + { + query: `{ } | select(.name,name)`, + conditions: []Condition{}, + secondPassConditions: []Condition{ + newCondition(NewAttribute("name"), OpNone), + newCondition(NewIntrinsic(IntrinsicName), OpNone), + }, + allConditions: false, + }, + } + for _, tt := range tests { + t.Run(tt.query, func(t *testing.T) { + expr, err := Parse(tt.query) + require.NoError(t, err) + + req := &FetchSpansRequest{ + Conditions: []Condition{}, + AllConditions: true, + } + expr.Pipeline.extractConditions(req) + + assert.Equal(t, tt.conditions, req.Conditions) + assert.Equal(t, tt.secondPassConditions, req.SecondPassConditions) assert.Equal(t, tt.allConditions, req.AllConditions, "FetchSpansRequest.AllConditions") }) } diff --git a/pkg/traceql/ast_execute.go b/pkg/traceql/ast_execute.go index b0eed97f071..578a8b08963 100644 --- a/pkg/traceql/ast_execute.go +++ b/pkg/traceql/ast_execute.go @@ -107,6 +107,11 @@ func (o SpansetOperation) evaluate(input []*Spanset) (output []*Spanset, err err return output, nil } +// SelectOperation evaluate is a no-op b/c the fetch layer has already decorated the spans with the requested attributes +func (o SelectOperation) evaluate(input []*Spanset) (output []*Spanset, err error) { + return input, nil +} + func (f ScalarFilter) evaluate(input []*Spanset) (output []*Spanset, err error) { // TODO we solve this gap where pipeline elements and scalar binary diff --git a/pkg/traceql/ast_stringer.go b/pkg/traceql/ast_stringer.go index 3fe87dc7071..b18c9be25ac 100644 --- a/pkg/traceql/ast_stringer.go +++ b/pkg/traceql/ast_stringer.go @@ -26,6 +26,14 @@ func (o CoalesceOperation) String() string { return "coalesce()" } +func (o SelectOperation) String() string { + s := make([]string, 0, len(o.exprs)) + for _, e := range o.exprs { + s = append(s, e.String()) + } + return "select(" + strings.Join(s, ", ") + ")" +} + func (o ScalarOperation) String() string { return binaryOp(o.Op, o.LHS, o.RHS) } diff --git a/pkg/traceql/ast_validate.go b/pkg/traceql/ast_validate.go index 35947809f3d..c9d499bceaa 100644 --- a/pkg/traceql/ast_validate.go +++ b/pkg/traceql/ast_validate.go @@ -42,6 +42,16 @@ func (o CoalesceOperation) validate() error { return nil } +func (o SelectOperation) validate() error { + for _, e := range o.exprs { + if err := e.validate(); err != nil { + return err + } + } + + return nil +} + func (o ScalarOperation) validate() error { if err := o.LHS.validate(); err != nil { return err diff --git a/pkg/traceql/engine.go b/pkg/traceql/engine.go index ed5cd999317..f386a09a108 100644 --- a/pkg/traceql/engine.go +++ b/pkg/traceql/engine.go @@ -70,7 +70,7 @@ func (e *Engine) ExecuteSearch(ctx context.Context, searchReq *tempopb.SearchReq spansetsEvaluated := 0 // set up the expression evaluation as a filter to reduce data pulled - fetchSpansRequest.SecondPassConditions = metaConditions + fetchSpansRequest.SecondPassConditions = append(fetchSpansRequest.SecondPassConditions, metaConditions...) fetchSpansRequest.SecondPass = func(inSS *Spanset) ([]*Spanset, error) { if len(inSS.Spans) == 0 { return nil, nil diff --git a/pkg/traceql/expr.y b/pkg/traceql/expr.y index c99683873e7..ae33cf9f3fc 100644 --- a/pkg/traceql/expr.y +++ b/pkg/traceql/expr.y @@ -12,6 +12,8 @@ import ( root RootExpr groupOperation GroupOperation coalesceOperation CoalesceOperation + selectOperation SelectOperation + selectArgs []FieldExpression spansetExpression SpansetExpression spansetPipelineExpression SpansetExpression @@ -43,6 +45,8 @@ import ( %type root %type groupOperation %type coalesceOperation +%type selectOperation +%type selectArgs %type spansetExpression %type spansetPipelineExpression @@ -68,13 +72,13 @@ import ( %token INTEGER %token FLOAT %token DURATION -%token DOT OPEN_BRACE CLOSE_BRACE OPEN_PARENS CLOSE_PARENS +%token DOT OPEN_BRACE CLOSE_BRACE OPEN_PARENS CLOSE_PARENS COMMA NIL TRUE FALSE STATUS_ERROR STATUS_OK STATUS_UNSET KIND_UNSPECIFIED KIND_INTERNAL KIND_SERVER KIND_CLIENT KIND_PRODUCER KIND_CONSUMER IDURATION CHILDCOUNT NAME STATUS PARENT KIND PARENT_DOT RESOURCE_DOT SPAN_DOT COUNT AVG MAX MIN SUM - BY COALESCE + BY COALESCE SELECT END_ATTRIBUTE // Operators are listed with increasing precedence. @@ -116,10 +120,12 @@ spansetPipeline: spansetExpression { $$ = newPipeline($1) } | scalarFilter { $$ = newPipeline($1) } | groupOperation { $$ = newPipeline($1) } + | selectOperation { $$ = newPipeline($1) } | spansetPipeline PIPE spansetExpression { $$ = $1.addItem($3) } | spansetPipeline PIPE scalarFilter { $$ = $1.addItem($3) } | spansetPipeline PIPE groupOperation { $$ = $1.addItem($3) } | spansetPipeline PIPE coalesceOperation { $$ = $1.addItem($3) } + | spansetPipeline PIPE selectOperation { $$ = $1.addItem($3) } ; groupOperation: @@ -130,6 +136,15 @@ coalesceOperation: COALESCE OPEN_PARENS CLOSE_PARENS { $$ = newCoalesceOperation() } ; +selectOperation: + SELECT OPEN_PARENS selectArgs CLOSE_PARENS { $$ = newSelectOperation($3) } + ; + +selectArgs: + fieldExpression { $$ = []FieldExpression{$1} } + | selectArgs COMMA fieldExpression { $$ = append($1, $3) } + ; + spansetExpression: // shares the same operators as scalarPipelineExpression. split out for readability OPEN_PARENS spansetExpression CLOSE_PARENS { $$ = $2 } | spansetExpression AND spansetExpression { $$ = newSpansetOperation(OpSpansetAnd, $1, $3) } diff --git a/pkg/traceql/expr.y.go b/pkg/traceql/expr.y.go index 33c1e763a2e..2d92118f7e5 100644 --- a/pkg/traceql/expr.y.go +++ b/pkg/traceql/expr.y.go @@ -17,6 +17,8 @@ type yySymType struct { root RootExpr groupOperation GroupOperation coalesceOperation CoalesceOperation + selectOperation SelectOperation + selectArgs []FieldExpression spansetExpression SpansetExpression spansetPipelineExpression SpansetExpression @@ -55,55 +57,57 @@ const OPEN_BRACE = 57352 const CLOSE_BRACE = 57353 const OPEN_PARENS = 57354 const CLOSE_PARENS = 57355 -const NIL = 57356 -const TRUE = 57357 -const FALSE = 57358 -const STATUS_ERROR = 57359 -const STATUS_OK = 57360 -const STATUS_UNSET = 57361 -const KIND_UNSPECIFIED = 57362 -const KIND_INTERNAL = 57363 -const KIND_SERVER = 57364 -const KIND_CLIENT = 57365 -const KIND_PRODUCER = 57366 -const KIND_CONSUMER = 57367 -const IDURATION = 57368 -const CHILDCOUNT = 57369 -const NAME = 57370 -const STATUS = 57371 -const PARENT = 57372 -const KIND = 57373 -const PARENT_DOT = 57374 -const RESOURCE_DOT = 57375 -const SPAN_DOT = 57376 -const COUNT = 57377 -const AVG = 57378 -const MAX = 57379 -const MIN = 57380 -const SUM = 57381 -const BY = 57382 -const COALESCE = 57383 -const END_ATTRIBUTE = 57384 -const PIPE = 57385 -const AND = 57386 -const OR = 57387 -const EQ = 57388 -const NEQ = 57389 -const LT = 57390 -const LTE = 57391 -const GT = 57392 -const GTE = 57393 -const NRE = 57394 -const RE = 57395 -const DESC = 57396 -const TILDE = 57397 -const ADD = 57398 -const SUB = 57399 -const NOT = 57400 -const MUL = 57401 -const DIV = 57402 -const MOD = 57403 -const POW = 57404 +const COMMA = 57356 +const NIL = 57357 +const TRUE = 57358 +const FALSE = 57359 +const STATUS_ERROR = 57360 +const STATUS_OK = 57361 +const STATUS_UNSET = 57362 +const KIND_UNSPECIFIED = 57363 +const KIND_INTERNAL = 57364 +const KIND_SERVER = 57365 +const KIND_CLIENT = 57366 +const KIND_PRODUCER = 57367 +const KIND_CONSUMER = 57368 +const IDURATION = 57369 +const CHILDCOUNT = 57370 +const NAME = 57371 +const STATUS = 57372 +const PARENT = 57373 +const KIND = 57374 +const PARENT_DOT = 57375 +const RESOURCE_DOT = 57376 +const SPAN_DOT = 57377 +const COUNT = 57378 +const AVG = 57379 +const MAX = 57380 +const MIN = 57381 +const SUM = 57382 +const BY = 57383 +const COALESCE = 57384 +const SELECT = 57385 +const END_ATTRIBUTE = 57386 +const PIPE = 57387 +const AND = 57388 +const OR = 57389 +const EQ = 57390 +const NEQ = 57391 +const LT = 57392 +const LTE = 57393 +const GT = 57394 +const GTE = 57395 +const NRE = 57396 +const RE = 57397 +const DESC = 57398 +const TILDE = 57399 +const ADD = 57400 +const SUB = 57401 +const NOT = 57402 +const MUL = 57403 +const DIV = 57404 +const MOD = 57405 +const POW = 57406 var yyToknames = [...]string{ "$end", @@ -119,6 +123,7 @@ var yyToknames = [...]string{ "CLOSE_BRACE", "OPEN_PARENS", "CLOSE_PARENS", + "COMMA", "NIL", "TRUE", "FALSE", @@ -147,6 +152,7 @@ var yyToknames = [...]string{ "SUM", "BY", "COALESCE", + "SELECT", "END_ATTRIBUTE", "PIPE", "AND", @@ -180,188 +186,199 @@ var yyExca = [...]int{ -1, 1, 1, -1, -2, 0, - -1, 185, - 13, 48, - -2, 56, + -1, 191, + 13, 53, + -2, 61, } const yyPrivate = 57344 -const yyLast = 600 +const yyLast = 653 var yyAct = [...]int{ - 12, 5, 183, 2, 65, 6, 7, 16, 163, 42, - 39, 38, 150, 151, 62, 152, 153, 154, 163, 57, - 58, 49, 59, 60, 61, 62, 33, 126, 106, 26, - 34, 36, 107, 108, 118, 120, 121, 122, 123, 155, - 156, 157, 158, 159, 160, 162, 161, 216, 218, 150, - 151, 217, 152, 153, 154, 163, 209, 140, 142, 143, - 144, 145, 146, 147, 152, 153, 154, 163, 148, 208, - 130, 166, 167, 168, 72, 73, 74, 78, 94, 207, - 64, 66, 206, 77, 75, 76, 80, 79, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 93, - 92, 97, 95, 96, 15, 125, 119, 176, 177, 178, - 179, 181, 180, 57, 58, 175, 59, 60, 61, 62, - 129, 180, 59, 60, 61, 62, 67, 68, 106, 182, - 133, 113, 107, 108, 185, 26, 187, 46, 47, 48, - 49, 125, 181, 105, 17, 18, 19, 28, 15, 104, - 110, 29, 31, 172, 69, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 126, 103, 21, 24, 22, 23, 25, 13, 111, - 102, 101, 173, 174, 63, 42, 39, 42, 39, 187, - 72, 73, 74, 78, 94, 20, 211, 66, 132, 77, - 75, 76, 80, 79, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 93, 92, 97, 95, 96, - 215, 50, 51, 52, 53, 54, 55, 56, 98, 99, - 100, 57, 58, 210, 59, 60, 61, 62, 43, 214, - 171, 170, 67, 68, 44, 45, 169, 46, 47, 48, - 49, 164, 165, 155, 156, 157, 158, 159, 160, 162, - 161, 213, 71, 150, 151, 70, 152, 153, 154, 163, - 164, 165, 155, 156, 157, 158, 159, 160, 162, 161, - 212, 41, 150, 151, 14, 152, 153, 154, 163, 4, - 11, 9, 164, 165, 155, 156, 157, 158, 159, 160, - 162, 161, 205, 109, 150, 151, 1, 152, 153, 154, - 163, 164, 165, 155, 156, 157, 158, 159, 160, 162, - 161, 188, 0, 150, 151, 0, 152, 153, 154, 163, - 0, 0, 0, 164, 165, 155, 156, 157, 158, 159, - 160, 162, 161, 149, 0, 150, 151, 0, 152, 153, - 154, 163, 164, 165, 155, 156, 157, 158, 159, 160, - 162, 161, 130, 0, 150, 151, 0, 152, 153, 154, - 163, 0, 0, 0, 0, 0, 164, 165, 155, 156, - 157, 158, 159, 160, 162, 161, 0, 0, 150, 151, - 0, 152, 153, 154, 163, 50, 51, 52, 53, 54, - 55, 128, 0, 0, 0, 57, 58, 0, 59, 60, - 61, 62, 50, 51, 52, 53, 54, 55, 0, 0, - 0, 0, 44, 45, 0, 46, 47, 48, 49, 17, - 18, 19, 0, 15, 0, 186, 17, 18, 19, 0, - 15, 0, 184, 0, 44, 45, 0, 46, 47, 48, - 49, 0, 0, 0, 0, 0, 0, 0, 21, 24, - 22, 23, 25, 13, 0, 21, 24, 22, 23, 25, - 13, 17, 18, 19, 0, 15, 0, 8, 37, 3, - 20, 0, 17, 18, 19, 0, 15, 20, 110, 0, - 0, 0, 0, 127, 0, 124, 0, 0, 0, 0, - 21, 24, 22, 23, 25, 13, 112, 114, 115, 116, - 117, 21, 24, 22, 23, 25, 0, 17, 18, 19, - 0, 0, 20, 141, 32, 35, 27, 30, 40, 10, - 33, 0, 28, 20, 34, 36, 29, 31, 0, 0, - 0, 0, 0, 0, 0, 0, 21, 24, 22, 23, - 25, 32, 35, 27, 30, 0, 0, 33, 0, 28, - 0, 34, 36, 29, 31, 0, 0, 0, 20, 0, - 0, 0, 131, 134, 135, 136, 137, 138, 139, 72, - 73, 74, 78, 0, 0, 0, 133, 0, 77, 75, - 76, 80, 79, 81, 82, 83, 84, 85, 86, 87, + 68, 6, 8, 5, 7, 189, 2, 18, 169, 64, + 223, 51, 130, 41, 28, 40, 156, 157, 227, 158, + 159, 160, 169, 158, 159, 160, 169, 13, 134, 72, + 110, 113, 109, 111, 226, 217, 129, 44, 122, 124, + 125, 126, 127, 170, 171, 161, 162, 163, 164, 165, + 166, 168, 167, 132, 216, 156, 157, 215, 158, 159, + 160, 169, 61, 62, 63, 64, 152, 154, 28, 214, + 172, 173, 174, 59, 60, 136, 61, 62, 63, 64, + 48, 49, 50, 51, 195, 196, 144, 146, 147, 148, + 149, 150, 151, 224, 181, 17, 129, 123, 46, 47, + 178, 48, 49, 50, 51, 133, 182, 183, 184, 185, + 161, 162, 163, 164, 165, 166, 168, 167, 186, 188, + 156, 157, 137, 158, 159, 160, 169, 186, 130, 117, + 179, 180, 110, 113, 109, 111, 108, 107, 191, 106, + 219, 222, 187, 193, 59, 60, 105, 61, 62, 63, + 64, 35, 104, 66, 65, 36, 38, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 187, 170, 171, 161, 162, 163, 164, + 165, 166, 168, 167, 218, 177, 156, 157, 176, 158, + 159, 160, 169, 175, 41, 74, 41, 225, 193, 170, + 171, 161, 162, 163, 164, 165, 166, 168, 167, 73, + 43, 156, 157, 16, 158, 159, 160, 169, 44, 4, + 44, 75, 76, 77, 81, 97, 12, 67, 69, 10, + 153, 80, 78, 79, 83, 82, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 96, 95, 100, + 98, 99, 46, 47, 58, 48, 49, 50, 51, 30, + 101, 102, 103, 31, 33, 221, 45, 75, 76, 77, + 81, 97, 112, 1, 69, 70, 71, 80, 78, 79, + 83, 82, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 96, 95, 100, 98, 99, 170, 171, + 161, 162, 163, 164, 165, 166, 168, 167, 220, 0, + 156, 157, 0, 158, 159, 160, 169, 0, 34, 37, + 0, 70, 71, 0, 35, 29, 32, 213, 36, 38, + 0, 30, 0, 0, 0, 31, 33, 0, 0, 0, + 0, 170, 171, 161, 162, 163, 164, 165, 166, 168, + 167, 194, 0, 156, 157, 0, 158, 159, 160, 169, + 170, 171, 161, 162, 163, 164, 165, 166, 168, 167, + 155, 0, 156, 157, 0, 158, 159, 160, 169, 0, + 0, 0, 0, 0, 170, 171, 161, 162, 163, 164, + 165, 166, 168, 167, 134, 0, 156, 157, 0, 158, + 159, 160, 169, 0, 0, 170, 171, 161, 162, 163, + 164, 165, 166, 168, 167, 0, 0, 156, 157, 0, + 158, 159, 160, 169, 0, 0, 0, 0, 0, 52, + 53, 54, 55, 56, 57, 0, 0, 0, 0, 59, + 60, 0, 61, 62, 63, 64, 52, 53, 54, 55, + 56, 57, 0, 0, 0, 0, 59, 60, 0, 61, + 62, 63, 64, 52, 53, 54, 55, 56, 57, 0, + 0, 0, 0, 46, 47, 0, 48, 49, 50, 51, + 19, 20, 21, 0, 17, 0, 114, 0, 19, 20, + 21, 0, 17, 0, 192, 0, 0, 19, 20, 21, + 0, 17, 0, 190, 0, 0, 0, 0, 0, 0, + 23, 26, 24, 25, 27, 14, 115, 15, 23, 26, + 24, 25, 27, 14, 0, 15, 0, 23, 26, 24, + 25, 27, 14, 22, 15, 0, 19, 20, 21, 0, + 17, 22, 9, 0, 0, 19, 20, 21, 0, 17, + 22, 114, 19, 20, 21, 0, 0, 131, 145, 0, + 128, 42, 11, 0, 0, 0, 23, 26, 24, 25, + 27, 14, 0, 15, 0, 23, 26, 24, 25, 27, + 0, 0, 23, 26, 24, 25, 27, 0, 0, 22, + 34, 37, 0, 29, 32, 0, 35, 0, 22, 30, + 36, 38, 0, 31, 33, 22, 0, 135, 138, 139, + 140, 141, 142, 143, 75, 76, 77, 81, 39, 3, + 0, 137, 0, 0, 80, 78, 79, 83, 82, 84, + 85, 86, 87, 88, 89, 90, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 116, 118, + 119, 120, 121, } var yyPact = [...]int{ - 465, -1000, -14, 509, -1000, 507, -1000, -1000, 465, -1000, - 366, -1000, 175, 172, -1000, 69, -1000, -1000, -1000, -1000, - 222, 169, 168, 160, 137, 131, 138, 119, 119, 119, - 119, 119, 94, 94, 94, 94, 94, 482, 128, 480, - 388, 107, 349, 574, 118, 118, 118, 118, 118, 118, - -1000, -1000, -1000, -1000, -1000, -1000, 511, 511, 511, 511, - 511, 511, 511, 185, -1000, 332, 185, 185, 185, -1000, + 530, -1000, -31, 279, -1000, 272, -1000, -1000, -1000, 530, + -1000, 415, -1000, 398, 142, 141, -1000, 216, -1000, -1000, + -1000, -1000, 254, 140, 134, 127, 125, 124, 474, 117, + 117, 117, 117, 117, 85, 85, 85, 85, 85, 547, + 83, 544, 40, 92, 381, 609, 110, 110, 110, 110, + 110, 110, -1000, -1000, -1000, -1000, -1000, -1000, 546, 546, + 546, 546, 546, 546, 546, 262, 262, -1000, 359, 262, + 262, 262, -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, 242, 237, 236, 149, -1000, -1000, - -1000, 102, 185, 185, 185, 185, 507, -1000, -1000, -1000, - 476, 117, 97, 430, -1000, -1000, 97, -1000, -24, 94, - -1000, -1000, -24, -1000, -1000, -1000, 138, -1000, -1000, -1000, - -1000, 188, -1000, 423, 78, 78, -41, -41, -41, -41, - -37, 511, 63, 63, -48, -48, -48, -48, 308, -1000, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 289, 5, 5, 40, - 37, 27, 14, 229, 192, -1000, 267, 248, 226, 207, - 480, 57, 34, 92, 430, -1000, 423, -16, -1000, 5, - 5, -54, -54, -54, -44, -44, -44, -44, -44, -44, - -44, -44, -54, -7, -7, -1000, -1000, -1000, -1000, -1000, - 9, 6, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 189, 184, 181, + 96, -1000, -1000, -1000, 81, 262, 262, 262, 262, 272, + -1000, -1000, -1000, -1000, 539, 107, 207, 491, -1000, -1000, + 207, -1000, 99, 85, -1000, -1000, 99, -1000, -1000, -1000, + 474, -1000, -1000, -1000, -1000, 194, -1000, 482, 19, 19, + -53, -53, -53, -53, 86, 546, 1, 1, -55, -55, + -55, -55, 338, 71, 153, -1000, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 314, -38, -38, 25, 13, 10, -9, 180, + 136, -1000, 295, 252, 128, -3, 544, 15, 80, 23, + 491, -1000, 482, -33, -1000, -1000, 262, -38, -38, -56, + -56, -56, -42, -42, -42, -42, -42, -42, -42, -42, + -56, 62, 62, -1000, -1000, -1000, -1000, -1000, -10, -26, + -1000, -1000, -1000, -1000, -1000, 153, -1000, -1000, } var yyPgo = [...]int{ - 0, 306, 6, 303, 1, 478, 291, 2, 290, 5, - 227, 289, 528, 0, 284, 281, 7, 4, 154, 265, - 262, + 0, 273, 4, 272, 2, 230, 3, 618, 229, 5, + 226, 1, 254, 219, 561, 27, 213, 210, 7, 0, + 29, 209, 195, } var yyR1 = [...]int{ - 0, 1, 1, 1, 5, 5, 5, 5, 5, 5, - 5, 6, 7, 7, 7, 7, 7, 7, 7, 2, - 3, 4, 4, 4, 4, 4, 4, 4, 8, 8, - 9, 10, 10, 10, 10, 10, 10, 11, 11, 12, - 12, 12, 12, 12, 12, 12, 12, 14, 15, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 16, 16, 16, 16, 16, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, - 19, 19, 20, 20, 20, 20, 20, 20, + 0, 1, 1, 1, 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, 10, 10, 11, 12, 12, 12, 12, + 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, + 14, 14, 16, 17, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 18, 18, + 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 21, 21, 21, 21, 21, 21, 22, 22, 22, + 22, 22, 22, } var yyR2 = [...]int{ 0, 1, 1, 1, 3, 3, 3, 3, 3, 3, - 1, 3, 1, 1, 1, 3, 3, 3, 3, 4, - 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, 3, 3, 3, 3, 3, 1, 1, 1, 1, - 2, 2, 2, 3, 4, 4, 4, 4, 3, 3, + 1, 3, 1, 1, 1, 1, 3, 3, 3, 3, + 3, 4, 3, 4, 1, 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, 3, 3, 3, 3, + 3, 1, 1, 1, 1, 2, 2, 2, 3, 4, + 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 3, 3, 3, 4, 4, + 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, + 3, 4, 4, } var yyChk = [...]int{ - -1000, -1, -7, -5, -11, -4, -9, -2, 12, -6, - -12, -8, -13, 40, -14, 10, -16, 6, 7, 8, - 57, 35, 37, 38, 36, 39, 43, 44, 50, 54, - 45, 55, 44, 50, 54, 45, 55, -5, -7, -4, - -12, -15, -13, -10, 56, 57, 59, 60, 61, 62, - 46, 47, 48, 49, 50, 51, -10, 56, 57, 59, - 60, 61, 62, 12, 11, -17, 12, 57, 58, -18, - -19, -20, 5, 6, 7, 15, 16, 14, 8, 18, - 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 31, 30, 9, 33, 34, 32, 6, 7, - 8, 12, 12, 12, 12, 12, -4, -9, -2, -3, - 12, 41, -5, 12, -5, -5, -5, -5, -4, 12, - -4, -4, -4, -4, 13, 13, 43, 13, 13, 13, - 13, -12, -18, 12, -12, -12, -12, -12, -12, -12, - -13, 12, -13, -13, -13, -13, -13, -13, -17, 11, - 56, 57, 59, 60, 61, 46, 47, 48, 49, 50, - 51, 53, 52, 62, 44, 45, -17, -17, -17, 4, - 4, 4, 4, 33, 34, 13, -17, -17, -17, -17, - -4, -13, 12, -7, 12, -16, 12, -7, 13, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, 13, 42, 42, 42, 42, - 4, 4, 13, 13, 13, 13, 13, 42, 42, + -1000, -1, -9, -7, -13, -6, -11, -2, -4, 12, + -8, -14, -10, -15, 41, 43, -16, 10, -18, 6, + 7, 8, 59, 36, 38, 39, 37, 40, 45, 46, + 52, 56, 47, 57, 46, 52, 56, 47, 57, -7, + -9, -6, -14, -17, -15, -12, 58, 59, 61, 62, + 63, 64, 48, 49, 50, 51, 52, 53, -12, 58, + 59, 61, 62, 63, 64, 12, 12, 11, -19, 12, + 59, 60, -20, -21, -22, 5, 6, 7, 16, 17, + 15, 8, 19, 18, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 32, 31, 9, 34, 35, + 33, 6, 7, 8, 12, 12, 12, 12, 12, -6, + -11, -2, -3, -4, 12, 42, -7, 12, -7, -7, + -7, -7, -6, 12, -6, -6, -6, -6, 13, 13, + 45, 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, 58, 59, 61, 62, + 63, 48, 49, 50, 51, 52, 53, 55, 54, 64, + 46, 47, -19, -19, -19, 4, 4, 4, 4, 34, + 35, 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, -19, -19, + -19, -19, -19, 13, 44, 44, 44, 44, 4, 4, + 13, 13, 13, 13, 13, -19, 44, 44, } var yyDef = [...]int{ - 0, -2, 1, 2, 3, 12, 13, 14, 0, 10, - 0, 27, 0, 0, 46, 0, 56, 57, 58, 59, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, + 0, -2, 1, 2, 3, 12, 13, 14, 15, 0, + 10, 0, 32, 0, 0, 0, 51, 0, 61, 62, + 63, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 31, 32, 33, 34, 35, 36, 0, 0, 0, 0, - 0, 0, 0, 0, 28, 0, 0, 0, 0, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 0, 0, 0, 0, 60, 61, - 62, 0, 0, 0, 0, 0, 15, 16, 17, 18, - 0, 0, 5, 0, 6, 7, 8, 9, 22, 0, - 23, 24, 25, 26, 4, 11, 0, 21, 39, 47, - 49, 37, 38, 0, 40, 41, 42, 43, 44, 45, - 30, 0, 50, 51, 52, 53, 54, 55, 0, 29, + 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 36, 37, 38, 39, 40, 41, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 0, 0, 0, + 0, 65, 66, 67, 0, 0, 0, 0, 0, 16, + 17, 18, 19, 20, 0, 0, 5, 0, 6, 7, + 8, 9, 27, 0, 28, 29, 30, 31, 4, 11, + 0, 26, 44, 52, 54, 42, 43, 0, 45, 46, + 47, 48, 49, 50, 35, 0, 55, 56, 57, 58, + 59, 60, 0, 0, 24, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 85, 86, 0, - 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -2, 0, 0, 19, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 68, 112, 113, 114, 115, - 0, 0, 64, 65, 66, 67, 20, 116, 117, + 0, 0, 0, 90, 91, 0, 0, 0, 0, 0, + 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, 0, 0, 21, 23, 0, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 73, 117, 118, 119, 120, 0, 0, + 69, 70, 71, 72, 22, 25, 121, 122, } var yyTok1 = [...]int{ @@ -375,7 +392,7 @@ 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, + 62, 63, 64, } var yyTok3 = [...]int{ 0, @@ -720,703 +737,733 @@ yydefault: case 1: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:94 +//line pkg/traceql/expr.y:98 { yylex.(*lexer).expr = newRootExpr(yyDollar[1].spansetPipeline) } case 2: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:95 +//line pkg/traceql/expr.y:99 { yylex.(*lexer).expr = newRootExpr(yyDollar[1].spansetPipelineExpression) } case 3: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:96 +//line pkg/traceql/expr.y:100 { yylex.(*lexer).expr = newRootExpr(yyDollar[1].scalarPipelineExpressionFilter) } case 4: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:103 +//line pkg/traceql/expr.y:107 { yyVAL.spansetPipelineExpression = yyDollar[2].spansetPipelineExpression } case 5: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:104 +//line pkg/traceql/expr.y:108 { yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetAnd, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) } case 6: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:105 +//line pkg/traceql/expr.y:109 { yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetChild, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) } case 7: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:106 +//line pkg/traceql/expr.y:110 { yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetDescendant, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) } case 8: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:107 +//line pkg/traceql/expr.y:111 { yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetUnion, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) } case 9: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:108 +//line pkg/traceql/expr.y:112 { yyVAL.spansetPipelineExpression = newSpansetOperation(OpSpansetSibling, yyDollar[1].spansetPipelineExpression, yyDollar[3].spansetPipelineExpression) } case 10: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:109 +//line pkg/traceql/expr.y:113 { yyVAL.spansetPipelineExpression = yyDollar[1].wrappedSpansetPipeline } case 11: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:113 +//line pkg/traceql/expr.y:117 { yyVAL.wrappedSpansetPipeline = yyDollar[2].spansetPipeline } case 12: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:116 +//line pkg/traceql/expr.y:120 { yyVAL.spansetPipeline = newPipeline(yyDollar[1].spansetExpression) } case 13: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:117 +//line pkg/traceql/expr.y:121 { yyVAL.spansetPipeline = newPipeline(yyDollar[1].scalarFilter) } case 14: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:118 +//line pkg/traceql/expr.y:122 { yyVAL.spansetPipeline = newPipeline(yyDollar[1].groupOperation) } case 15: + yyDollar = yyS[yypt-1 : yypt+1] +//line pkg/traceql/expr.y:123 + { + yyVAL.spansetPipeline = newPipeline(yyDollar[1].selectOperation) + } + case 16: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:119 +//line pkg/traceql/expr.y:124 { yyVAL.spansetPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].spansetExpression) } - case 16: + case 17: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:120 +//line pkg/traceql/expr.y:125 { yyVAL.spansetPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].scalarFilter) } - case 17: + case 18: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:121 +//line pkg/traceql/expr.y:126 { yyVAL.spansetPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].groupOperation) } - case 18: + case 19: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:122 +//line pkg/traceql/expr.y:127 { yyVAL.spansetPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].coalesceOperation) } - case 19: + case 20: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:128 + { + yyVAL.spansetPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].selectOperation) + } + case 21: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:126 +//line pkg/traceql/expr.y:132 { yyVAL.groupOperation = newGroupOperation(yyDollar[3].fieldExpression) } - case 20: + case 22: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:130 +//line pkg/traceql/expr.y:136 { yyVAL.coalesceOperation = newCoalesceOperation() } - case 21: + case 23: + yyDollar = yyS[yypt-4 : yypt+1] +//line pkg/traceql/expr.y:140 + { + yyVAL.selectOperation = newSelectOperation(yyDollar[3].selectArgs) + } + case 24: + yyDollar = yyS[yypt-1 : yypt+1] +//line pkg/traceql/expr.y:144 + { + yyVAL.selectArgs = []FieldExpression{yyDollar[1].fieldExpression} + } + case 25: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:145 + { + yyVAL.selectArgs = append(yyDollar[1].selectArgs, yyDollar[3].fieldExpression) + } + case 26: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:134 +//line pkg/traceql/expr.y:149 { yyVAL.spansetExpression = yyDollar[2].spansetExpression } - case 22: + case 27: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:135 +//line pkg/traceql/expr.y:150 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetAnd, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 23: + case 28: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:136 +//line pkg/traceql/expr.y:151 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetChild, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 24: + case 29: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:137 +//line pkg/traceql/expr.y:152 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetDescendant, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 25: + case 30: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:138 +//line pkg/traceql/expr.y:153 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetUnion, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 26: + case 31: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:139 +//line pkg/traceql/expr.y:154 { yyVAL.spansetExpression = newSpansetOperation(OpSpansetSibling, yyDollar[1].spansetExpression, yyDollar[3].spansetExpression) } - case 27: + case 32: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:140 +//line pkg/traceql/expr.y:155 { yyVAL.spansetExpression = yyDollar[1].spansetFilter } - case 28: + case 33: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:144 +//line pkg/traceql/expr.y:159 { yyVAL.spansetFilter = newSpansetFilter(NewStaticBool(true)) } - case 29: + case 34: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:145 +//line pkg/traceql/expr.y:160 { yyVAL.spansetFilter = newSpansetFilter(yyDollar[2].fieldExpression) } - case 30: + case 35: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:149 +//line pkg/traceql/expr.y:164 { yyVAL.scalarFilter = newScalarFilter(yyDollar[2].scalarFilterOperation, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 31: + case 36: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:153 +//line pkg/traceql/expr.y:168 { yyVAL.scalarFilterOperation = OpEqual } - case 32: + case 37: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:154 +//line pkg/traceql/expr.y:169 { yyVAL.scalarFilterOperation = OpNotEqual } - case 33: + case 38: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:155 +//line pkg/traceql/expr.y:170 { yyVAL.scalarFilterOperation = OpLess } - case 34: + case 39: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:156 +//line pkg/traceql/expr.y:171 { yyVAL.scalarFilterOperation = OpLessEqual } - case 35: + case 40: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:157 +//line pkg/traceql/expr.y:172 { yyVAL.scalarFilterOperation = OpGreater } - case 36: + case 41: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:158 +//line pkg/traceql/expr.y:173 { yyVAL.scalarFilterOperation = OpGreaterEqual } - case 37: + case 42: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:165 +//line pkg/traceql/expr.y:180 { yyVAL.scalarPipelineExpressionFilter = newScalarFilter(yyDollar[2].scalarFilterOperation, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 38: + case 43: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:166 +//line pkg/traceql/expr.y:181 { yyVAL.scalarPipelineExpressionFilter = newScalarFilter(yyDollar[2].scalarFilterOperation, yyDollar[1].scalarPipelineExpression, yyDollar[3].static) } - case 39: + case 44: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:170 +//line pkg/traceql/expr.y:185 { yyVAL.scalarPipelineExpression = yyDollar[2].scalarPipelineExpression } - case 40: + case 45: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:171 +//line pkg/traceql/expr.y:186 { yyVAL.scalarPipelineExpression = newScalarOperation(OpAdd, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 41: + case 46: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:172 +//line pkg/traceql/expr.y:187 { yyVAL.scalarPipelineExpression = newScalarOperation(OpSub, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 42: + case 47: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:173 +//line pkg/traceql/expr.y:188 { yyVAL.scalarPipelineExpression = newScalarOperation(OpMult, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 43: + case 48: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:174 +//line pkg/traceql/expr.y:189 { yyVAL.scalarPipelineExpression = newScalarOperation(OpDiv, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 44: + case 49: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:175 +//line pkg/traceql/expr.y:190 { yyVAL.scalarPipelineExpression = newScalarOperation(OpMod, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 45: + case 50: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:176 +//line pkg/traceql/expr.y:191 { yyVAL.scalarPipelineExpression = newScalarOperation(OpPower, yyDollar[1].scalarPipelineExpression, yyDollar[3].scalarPipelineExpression) } - case 46: + case 51: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:177 +//line pkg/traceql/expr.y:192 { yyVAL.scalarPipelineExpression = yyDollar[1].wrappedScalarPipeline } - case 47: + case 52: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:181 +//line pkg/traceql/expr.y:196 { yyVAL.wrappedScalarPipeline = yyDollar[2].scalarPipeline } - case 48: + case 53: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:185 +//line pkg/traceql/expr.y:200 { yyVAL.scalarPipeline = yyDollar[1].spansetPipeline.addItem(yyDollar[3].aggregate) } - case 49: + case 54: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:189 +//line pkg/traceql/expr.y:204 { yyVAL.scalarExpression = yyDollar[2].scalarExpression } - case 50: + case 55: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:190 +//line pkg/traceql/expr.y:205 { yyVAL.scalarExpression = newScalarOperation(OpAdd, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 51: + case 56: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:191 +//line pkg/traceql/expr.y:206 { yyVAL.scalarExpression = newScalarOperation(OpSub, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 52: + case 57: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:192 +//line pkg/traceql/expr.y:207 { yyVAL.scalarExpression = newScalarOperation(OpMult, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 53: + case 58: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:193 +//line pkg/traceql/expr.y:208 { yyVAL.scalarExpression = newScalarOperation(OpDiv, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 54: + case 59: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:194 +//line pkg/traceql/expr.y:209 { yyVAL.scalarExpression = newScalarOperation(OpMod, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 55: + case 60: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:195 +//line pkg/traceql/expr.y:210 { yyVAL.scalarExpression = newScalarOperation(OpPower, yyDollar[1].scalarExpression, yyDollar[3].scalarExpression) } - case 56: + case 61: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:196 +//line pkg/traceql/expr.y:211 { yyVAL.scalarExpression = yyDollar[1].aggregate } - case 57: + case 62: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:197 +//line pkg/traceql/expr.y:212 { yyVAL.scalarExpression = NewStaticInt(yyDollar[1].staticInt) } - case 58: + case 63: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:198 +//line pkg/traceql/expr.y:213 { yyVAL.scalarExpression = NewStaticFloat(yyDollar[1].staticFloat) } - case 59: + case 64: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:199 +//line pkg/traceql/expr.y:214 { yyVAL.scalarExpression = NewStaticDuration(yyDollar[1].staticDuration) } - case 60: + case 65: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:200 +//line pkg/traceql/expr.y:215 { yyVAL.scalarExpression = NewStaticInt(-yyDollar[2].staticInt) } - case 61: + case 66: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:201 +//line pkg/traceql/expr.y:216 { yyVAL.scalarExpression = NewStaticFloat(-yyDollar[2].staticFloat) } - case 62: + case 67: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:202 +//line pkg/traceql/expr.y:217 { yyVAL.scalarExpression = NewStaticDuration(-yyDollar[2].staticDuration) } - case 63: + case 68: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:206 +//line pkg/traceql/expr.y:221 { yyVAL.aggregate = newAggregate(aggregateCount, nil) } - case 64: + case 69: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:207 +//line pkg/traceql/expr.y:222 { yyVAL.aggregate = newAggregate(aggregateMax, yyDollar[3].fieldExpression) } - case 65: + case 70: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:208 +//line pkg/traceql/expr.y:223 { yyVAL.aggregate = newAggregate(aggregateMin, yyDollar[3].fieldExpression) } - case 66: + case 71: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:209 +//line pkg/traceql/expr.y:224 { yyVAL.aggregate = newAggregate(aggregateAvg, yyDollar[3].fieldExpression) } - case 67: + case 72: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:210 +//line pkg/traceql/expr.y:225 { yyVAL.aggregate = newAggregate(aggregateSum, yyDollar[3].fieldExpression) } - case 68: + case 73: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:217 +//line pkg/traceql/expr.y:232 { yyVAL.fieldExpression = yyDollar[2].fieldExpression } - case 69: + case 74: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:218 +//line pkg/traceql/expr.y:233 { yyVAL.fieldExpression = newBinaryOperation(OpAdd, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 70: + case 75: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:219 +//line pkg/traceql/expr.y:234 { yyVAL.fieldExpression = newBinaryOperation(OpSub, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 71: + case 76: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:220 +//line pkg/traceql/expr.y:235 { yyVAL.fieldExpression = newBinaryOperation(OpMult, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 72: + case 77: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:221 +//line pkg/traceql/expr.y:236 { yyVAL.fieldExpression = newBinaryOperation(OpDiv, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 73: + case 78: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:222 +//line pkg/traceql/expr.y:237 { yyVAL.fieldExpression = newBinaryOperation(OpMod, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 74: + case 79: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:223 +//line pkg/traceql/expr.y:238 { yyVAL.fieldExpression = newBinaryOperation(OpEqual, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 75: + case 80: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:224 +//line pkg/traceql/expr.y:239 { yyVAL.fieldExpression = newBinaryOperation(OpNotEqual, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 76: + case 81: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:225 +//line pkg/traceql/expr.y:240 { yyVAL.fieldExpression = newBinaryOperation(OpLess, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 77: + case 82: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:226 +//line pkg/traceql/expr.y:241 { yyVAL.fieldExpression = newBinaryOperation(OpLessEqual, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 78: + case 83: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:227 +//line pkg/traceql/expr.y:242 { yyVAL.fieldExpression = newBinaryOperation(OpGreater, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 79: + case 84: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:228 +//line pkg/traceql/expr.y:243 { yyVAL.fieldExpression = newBinaryOperation(OpGreaterEqual, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 80: + case 85: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:229 +//line pkg/traceql/expr.y:244 { yyVAL.fieldExpression = newBinaryOperation(OpRegex, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 81: + case 86: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:230 +//line pkg/traceql/expr.y:245 { yyVAL.fieldExpression = newBinaryOperation(OpNotRegex, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 82: + case 87: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:231 +//line pkg/traceql/expr.y:246 { yyVAL.fieldExpression = newBinaryOperation(OpPower, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 83: + case 88: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:232 +//line pkg/traceql/expr.y:247 { yyVAL.fieldExpression = newBinaryOperation(OpAnd, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 84: + case 89: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:233 +//line pkg/traceql/expr.y:248 { yyVAL.fieldExpression = newBinaryOperation(OpOr, yyDollar[1].fieldExpression, yyDollar[3].fieldExpression) } - case 85: + case 90: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:234 +//line pkg/traceql/expr.y:249 { yyVAL.fieldExpression = newUnaryOperation(OpSub, yyDollar[2].fieldExpression) } - case 86: + case 91: yyDollar = yyS[yypt-2 : yypt+1] -//line pkg/traceql/expr.y:235 +//line pkg/traceql/expr.y:250 { yyVAL.fieldExpression = newUnaryOperation(OpNot, yyDollar[2].fieldExpression) } - case 87: + case 92: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:236 +//line pkg/traceql/expr.y:251 { yyVAL.fieldExpression = yyDollar[1].static } - case 88: + case 93: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:237 +//line pkg/traceql/expr.y:252 { yyVAL.fieldExpression = yyDollar[1].intrinsicField } - case 89: + case 94: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:238 +//line pkg/traceql/expr.y:253 { yyVAL.fieldExpression = yyDollar[1].attributeField } - case 90: + case 95: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:245 +//line pkg/traceql/expr.y:260 { yyVAL.static = NewStaticString(yyDollar[1].staticStr) } - case 91: + case 96: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:246 +//line pkg/traceql/expr.y:261 { yyVAL.static = NewStaticInt(yyDollar[1].staticInt) } - case 92: + case 97: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:247 +//line pkg/traceql/expr.y:262 { yyVAL.static = NewStaticFloat(yyDollar[1].staticFloat) } - case 93: + case 98: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:248 +//line pkg/traceql/expr.y:263 { yyVAL.static = NewStaticBool(true) } - case 94: + case 99: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:249 +//line pkg/traceql/expr.y:264 { yyVAL.static = NewStaticBool(false) } - case 95: + case 100: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:250 +//line pkg/traceql/expr.y:265 { yyVAL.static = NewStaticNil() } - case 96: + case 101: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:251 +//line pkg/traceql/expr.y:266 { yyVAL.static = NewStaticDuration(yyDollar[1].staticDuration) } - case 97: + case 102: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:252 +//line pkg/traceql/expr.y:267 { yyVAL.static = NewStaticStatus(StatusOk) } - case 98: + case 103: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:253 +//line pkg/traceql/expr.y:268 { yyVAL.static = NewStaticStatus(StatusError) } - case 99: + case 104: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:254 +//line pkg/traceql/expr.y:269 { yyVAL.static = NewStaticStatus(StatusUnset) } - case 100: + case 105: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:255 +//line pkg/traceql/expr.y:270 { yyVAL.static = NewStaticKind(KindUnspecified) } - case 101: + case 106: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:256 +//line pkg/traceql/expr.y:271 { yyVAL.static = NewStaticKind(KindInternal) } - case 102: + case 107: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:257 +//line pkg/traceql/expr.y:272 { yyVAL.static = NewStaticKind(KindServer) } - case 103: + case 108: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:258 +//line pkg/traceql/expr.y:273 { yyVAL.static = NewStaticKind(KindClient) } - case 104: + case 109: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:259 +//line pkg/traceql/expr.y:274 { yyVAL.static = NewStaticKind(KindProducer) } - case 105: + case 110: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:260 +//line pkg/traceql/expr.y:275 { yyVAL.static = NewStaticKind(KindConsumer) } - case 106: + case 111: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:264 +//line pkg/traceql/expr.y:279 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicDuration) } - case 107: + case 112: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:265 +//line pkg/traceql/expr.y:280 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicChildCount) } - case 108: + case 113: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:266 +//line pkg/traceql/expr.y:281 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicName) } - case 109: + case 114: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:267 +//line pkg/traceql/expr.y:282 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicStatus) } - case 110: + case 115: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:268 +//line pkg/traceql/expr.y:283 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicKind) } - case 111: + case 116: yyDollar = yyS[yypt-1 : yypt+1] -//line pkg/traceql/expr.y:269 +//line pkg/traceql/expr.y:284 { yyVAL.intrinsicField = NewIntrinsic(IntrinsicParent) } - case 112: + case 117: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:273 +//line pkg/traceql/expr.y:288 { yyVAL.attributeField = NewAttribute(yyDollar[2].staticStr) } - case 113: + case 118: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:274 +//line pkg/traceql/expr.y:289 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, false, yyDollar[2].staticStr) } - case 114: + case 119: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:275 +//line pkg/traceql/expr.y:290 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, false, yyDollar[2].staticStr) } - case 115: + case 120: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:276 +//line pkg/traceql/expr.y:291 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeNone, true, yyDollar[2].staticStr) } - case 116: + case 121: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:277 +//line pkg/traceql/expr.y:292 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, true, yyDollar[3].staticStr) } - case 117: + case 122: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:278 +//line pkg/traceql/expr.y:293 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, true, yyDollar[3].staticStr) } diff --git a/pkg/traceql/lexer.go b/pkg/traceql/lexer.go index f56d82406b9..a539f47eaf2 100644 --- a/pkg/traceql/lexer.go +++ b/pkg/traceql/lexer.go @@ -11,6 +11,7 @@ import ( ) var tokens = map[string]int{ + ",": COMMA, ".": DOT, "{": OPEN_BRACE, "}": CLOSE_BRACE, @@ -64,6 +65,7 @@ var tokens = map[string]int{ "sum": SUM, "by": BY, "coalesce": COALESCE, + "select": SELECT, } type lexer struct { @@ -245,7 +247,7 @@ func isAttributeRune(r rune) bool { } switch r { - case scanner.EOF, '{', '}', '(', ')', '=', '~', '!', '<', '>', '&', '|', '^': + case scanner.EOF, '{', '}', '(', ')', '=', '~', '!', '<', '>', '&', '|', '^', ',': return false default: return true diff --git a/pkg/traceql/lexer_test.go b/pkg/traceql/lexer_test.go index 3a4445b30f5..401fa1229bc 100644 --- a/pkg/traceql/lexer_test.go +++ b/pkg/traceql/lexer_test.go @@ -52,12 +52,13 @@ 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}}, {`.foo).bar`, []int{DOT, IDENTIFIER, END_ATTRIBUTE, CLOSE_PARENS, DOT, IDENTIFIER, END_ATTRIBUTE}}, {`.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}}, // not attributes {`.3`, []int{FLOAT}}, diff --git a/pkg/traceql/parse_test.go b/pkg/traceql/parse_test.go index a7b33c7cb6f..7836f675e68 100644 --- a/pkg/traceql/parse_test.go +++ b/pkg/traceql/parse_test.go @@ -299,6 +299,42 @@ func TestGroupCoalesceOperation(t *testing.T) { } } +func TestSelectErrors(t *testing.T) { + tests := []struct { + in string + err error + }{ + {in: "select(.a) && { .b }", err: newParseError("syntax error: unexpected &&", 0, 12)}, + {in: "select()", err: newParseError("syntax error: unexpected )", 1, 8)}} + + for _, tc := range tests { + t.Run(tc.in, func(t *testing.T) { + _, err := Parse(tc.in) + + require.Equal(t, tc.err, err) + }) + } +} + +func TestSelectOperation(t *testing.T) { + tests := []struct { + in string + expected Pipeline + }{ + {in: "select(.a)", expected: newPipeline(newSelectOperation([]FieldExpression{NewAttribute("a")}))}, + {in: "select(.a,.b)", expected: newPipeline(newSelectOperation([]FieldExpression{NewAttribute("a"), NewAttribute("b")}))}, + } + + for _, tc := range tests { + t.Run(tc.in, func(t *testing.T) { + actual, err := Parse(tc.in) + + require.NoError(t, err) + require.Equal(t, &RootExpr{tc.expected}, actual) + }) + } +} + func TestSpansetExpressionErrors(t *testing.T) { tests := []struct { in string diff --git a/pkg/traceql/test_examples.yaml b/pkg/traceql/test_examples.yaml index 58ccf139f35..1606a3be95c 100644 --- a/pkg/traceql/test_examples.yaml +++ b/pkg/traceql/test_examples.yaml @@ -75,6 +75,9 @@ valid: - '{ true } | max(1 + .a) = 1' - '{ true } | max((1 + .a) * 2) = 1' - 'max(duration) > 3s | { status = error || .http.status = 500 }' + # select + - 'select(.a)' + - '{} | select(.a,.b,.c)' # pipelines - '{ true } | { .a }' - '{ true } | count() = 1' @@ -132,6 +135,9 @@ parse_fails: - 'avg(.field) + 1' # scalar filters must resolve to boolean - 'sum(3) - 2' - 'min(childCount) && 2' + # select + - 'select(.a' + - 'select()' # pipelines - 'coalesce() | { true }' # pipelines can't start with coalesce - 'count() > 3 && { true }' # scalar filters have to be in pipeline @@ -199,6 +205,8 @@ validate_fails: - 'min(1) = max(2) + 3' - 'min(1.1 - 3) > 1' - 'max(1h + 2h) > 1' + # select + - 'select(1 + "string")' # by - will *not* be valid when supported - group expressions must reference the span - '{ true } | by(1)' - '{ true } | by("foo")'