From 55227a17269dc98675919b80cbd0e5f3ba5bd4dd Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Thu, 14 Mar 2024 08:31:35 -0400 Subject: [PATCH 1/7] add nested set Signed-off-by: Joe Elliott --- pkg/search/util.go | 6 + pkg/traceql/ast.go | 6 + pkg/traceql/enum_attributes.go | 18 + pkg/traceql/expr.y | 5 +- pkg/traceql/expr.y.go | 452 ++++++++++-------- pkg/traceql/lexer.go | 4 +- pkg/traceql/lexer_test.go | 5 + pkg/traceql/parse_test.go | 3 + .../encoding/vparquet3/block_autocomplete.go | 6 +- tempodb/encoding/vparquet3/block_traceql.go | 50 +- 10 files changed, 340 insertions(+), 215 deletions(-) diff --git a/pkg/search/util.go b/pkg/search/util.go index 03e77dd4001..3e10e0f379e 100644 --- a/pkg/search/util.go +++ b/pkg/search/util.go @@ -64,5 +64,11 @@ func GetVirtualIntrinsicValues() []string { traceql.IntrinsicTraceDuration.String(), traceql.IntrinsicTraceRootService.String(), traceql.IntrinsicTraceRootSpan.String(), + /* these are technically intrinsics that can be requested, but they are not generally of interest to a user + typing a query. for simplicity and clarity we are leaving them out of autocomplete + IntrinsicNestedSetLeft + IntrinsicNestedSetRight + IntrinsicNestedSetParent + */ } } diff --git a/pkg/traceql/ast.go b/pkg/traceql/ast.go index 5c11fce49f6..894a12d41a3 100644 --- a/pkg/traceql/ast.go +++ b/pkg/traceql/ast.go @@ -702,6 +702,12 @@ func (a Attribute) impliedType() StaticType { return TypeString case IntrinsicTraceRootSpan: return TypeString + case IntrinsicNestedSetLeft: + return TypeInt + case IntrinsicNestedSetRight: + return TypeInt + case IntrinsicNestedSetParent: + return TypeInt } return TypeAttribute diff --git a/pkg/traceql/enum_attributes.go b/pkg/traceql/enum_attributes.go index dbbcfac3f7a..064400e016b 100644 --- a/pkg/traceql/enum_attributes.go +++ b/pkg/traceql/enum_attributes.go @@ -59,6 +59,9 @@ const ( IntrinsicTraceRootService IntrinsicTraceRootSpan IntrinsicTraceDuration + IntrinsicNestedSetLeft + IntrinsicNestedSetRight + IntrinsicNestedSetParent // not yet implemented in traceql but will be IntrinsicParent @@ -91,6 +94,9 @@ var ( IntrinsicTraceRootSpanAttribute = NewIntrinsic(IntrinsicTraceRootSpan) IntrinsicTraceDurationAttribute = NewIntrinsic(IntrinsicTraceDuration) IntrinsicSpanStartTimeAttribute = NewIntrinsic(IntrinsicSpanStartTime) + IntrinsicNestedSetLeftAttribute = NewIntrinsic(IntrinsicNestedSetLeft) + IntrinsicNestedSetRightAttribute = NewIntrinsic(IntrinsicNestedSetRight) + IntrinsicNestedSetParentAttribute = NewIntrinsic(IntrinsicNestedSetParent) ) func (i Intrinsic) String() string { @@ -126,6 +132,12 @@ func (i Intrinsic) String() string { return "spanID" case IntrinsicSpanStartTime: return "spanStartTime" + case IntrinsicNestedSetLeft: + return "nestedSetLeft" + case IntrinsicNestedSetRight: + return "nestedSetRight" + case IntrinsicNestedSetParent: + return "nestedSetParent" } return fmt.Sprintf("intrinsic(%d)", i) @@ -163,6 +175,12 @@ func intrinsicFromString(s string) Intrinsic { return IntrinsicSpanID case "spanStartTime": return IntrinsicSpanStartTime + case "nestedSetLeft": + return IntrinsicNestedSetLeft + case "nestedSetRight": + return IntrinsicNestedSetRight + case "nestedSetParent": + return IntrinsicNestedSetParent } return IntrinsicNone diff --git a/pkg/traceql/expr.y b/pkg/traceql/expr.y index e8faed41a88..4ad20d2ba1c 100644 --- a/pkg/traceql/expr.y +++ b/pkg/traceql/expr.y @@ -85,7 +85,7 @@ import ( %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 STATUS_MESSAGE PARENT KIND ROOTNAME ROOTSERVICENAME TRACEDURATION + IDURATION CHILDCOUNT NAME STATUS STATUS_MESSAGE PARENT KIND ROOTNAME ROOTSERVICENAME TRACEDURATION NESTEDSETLEFT NESTEDSETRIGHT NESTEDSETPARENT PARENT_DOT RESOURCE_DOT SPAN_DOT COUNT AVG MAX MIN SUM BY COALESCE SELECT @@ -345,6 +345,9 @@ intrinsicField: | ROOTNAME { $$ = NewIntrinsic(IntrinsicTraceRootSpan) } | ROOTSERVICENAME { $$ = NewIntrinsic(IntrinsicTraceRootService) } | TRACEDURATION { $$ = NewIntrinsic(IntrinsicTraceDuration) } + | NESTEDSETLEFT { $$ = NewIntrinsic(IntrinsicNestedSetLeft) } + | NESTEDSETRIGHT { $$ = NewIntrinsic(IntrinsicNestedSetRight) } + | NESTEDSETPARENT { $$ = NewIntrinsic(IntrinsicNestedSetParent) } ; attributeField: diff --git a/pkg/traceql/expr.y.go b/pkg/traceql/expr.y.go index 99bcbe057b3..57bbe8057f8 100644 --- a/pkg/traceql/expr.y.go +++ b/pkg/traceql/expr.y.go @@ -85,46 +85,49 @@ const KIND = 57375 const ROOTNAME = 57376 const ROOTSERVICENAME = 57377 const TRACEDURATION = 57378 -const PARENT_DOT = 57379 -const RESOURCE_DOT = 57380 -const SPAN_DOT = 57381 -const COUNT = 57382 -const AVG = 57383 -const MAX = 57384 -const MIN = 57385 -const SUM = 57386 -const BY = 57387 -const COALESCE = 57388 -const SELECT = 57389 -const END_ATTRIBUTE = 57390 -const RATE = 57391 -const COUNT_OVER_TIME = 57392 -const WITH = 57393 -const PIPE = 57394 -const AND = 57395 -const OR = 57396 -const EQ = 57397 -const NEQ = 57398 -const LT = 57399 -const LTE = 57400 -const GT = 57401 -const GTE = 57402 -const NRE = 57403 -const RE = 57404 -const DESC = 57405 -const ANCE = 57406 -const SIBL = 57407 -const NOT_CHILD = 57408 -const NOT_PARENT = 57409 -const NOT_DESC = 57410 -const NOT_ANCE = 57411 -const ADD = 57412 -const SUB = 57413 -const NOT = 57414 -const MUL = 57415 -const DIV = 57416 -const MOD = 57417 -const POW = 57418 +const NESTEDSETLEFT = 57379 +const NESTEDSETRIGHT = 57380 +const NESTEDSETPARENT = 57381 +const PARENT_DOT = 57382 +const RESOURCE_DOT = 57383 +const SPAN_DOT = 57384 +const COUNT = 57385 +const AVG = 57386 +const MAX = 57387 +const MIN = 57388 +const SUM = 57389 +const BY = 57390 +const COALESCE = 57391 +const SELECT = 57392 +const END_ATTRIBUTE = 57393 +const RATE = 57394 +const COUNT_OVER_TIME = 57395 +const WITH = 57396 +const PIPE = 57397 +const AND = 57398 +const OR = 57399 +const EQ = 57400 +const NEQ = 57401 +const LT = 57402 +const LTE = 57403 +const GT = 57404 +const GTE = 57405 +const NRE = 57406 +const RE = 57407 +const DESC = 57408 +const ANCE = 57409 +const SIBL = 57410 +const NOT_CHILD = 57411 +const NOT_PARENT = 57412 +const NOT_DESC = 57413 +const NOT_ANCE = 57414 +const ADD = 57415 +const SUB = 57416 +const NOT = 57417 +const MUL = 57418 +const DIV = 57419 +const MOD = 57420 +const POW = 57421 var yyToknames = [...]string{ "$end", @@ -163,6 +166,9 @@ var yyToknames = [...]string{ "ROOTNAME", "ROOTSERVICENAME", "TRACEDURATION", + "NESTEDSETLEFT", + "NESTEDSETRIGHT", + "NESTEDSETPARENT", "PARENT_DOT", "RESOURCE_DOT", "SPAN_DOT", @@ -215,135 +221,139 @@ var yyExca = [...]int{ -1, 1, 1, -1, -2, 0, - -1, 235, + -1, 238, 13, 71, -2, 79, } const yyPrivate = 57344 -const yyLast = 796 +const yyLast = 825 var yyAct = [...]int{ - 5, 90, 6, 89, 8, 191, 7, 88, 233, 2, - 57, 18, 226, 13, 84, 208, 267, 80, 56, 67, - 168, 195, 196, 60, 197, 198, 199, 208, 270, 167, - 30, 131, 167, 132, 29, 135, 278, 133, 197, 198, - 199, 208, 277, 261, 153, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 209, 210, 200, 201, - 202, 203, 204, 205, 207, 206, 266, 273, 274, 174, - 260, 168, 259, 195, 196, 172, 197, 198, 199, 208, - 77, 78, 79, 80, 193, 258, 192, 282, 182, 184, - 185, 186, 187, 188, 189, 281, 190, 288, 240, 272, - 211, 212, 213, 287, 240, 271, 209, 210, 200, 201, - 202, 203, 204, 205, 207, 206, 284, 68, 69, 70, - 71, 72, 73, 195, 196, 220, 197, 198, 199, 208, - 268, 269, 75, 76, 171, 77, 78, 79, 80, 230, - 221, 222, 223, 224, 227, 265, 68, 69, 70, 71, - 72, 73, 231, 75, 76, 230, 77, 78, 79, 80, - 283, 75, 76, 232, 77, 78, 79, 80, 229, 131, - 172, 132, 17, 135, 154, 133, 64, 65, 66, 67, - 235, 239, 240, 228, 237, 209, 210, 200, 201, 202, - 203, 204, 205, 207, 206, 62, 63, 231, 64, 65, - 66, 67, 195, 196, 170, 197, 198, 199, 208, 194, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 175, 75, 76, 141, - 77, 78, 79, 80, 129, 57, 128, 57, 127, 126, - 125, 124, 276, 82, 275, 237, 81, 263, 60, 217, - 60, 209, 210, 200, 201, 202, 203, 204, 205, 207, - 206, 62, 63, 262, 64, 65, 66, 67, 195, 196, - 216, 197, 198, 199, 208, 131, 28, 132, 280, 135, - 215, 133, 279, 218, 219, 193, 193, 192, 192, 285, - 286, 91, 92, 93, 97, 117, 214, 83, 85, 225, - 59, 96, 94, 95, 99, 98, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 113, 112, - 114, 115, 116, 120, 118, 119, 74, 200, 201, 202, - 203, 204, 205, 207, 206, 121, 122, 123, 61, 16, - 4, 130, 195, 196, 264, 197, 198, 199, 208, 91, - 92, 93, 97, 117, 12, 10, 85, 86, 87, 96, - 94, 95, 99, 98, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 113, 112, 114, 115, - 116, 120, 118, 119, 209, 210, 200, 201, 202, 203, - 204, 205, 207, 206, 257, 134, 1, 0, 0, 0, - 0, 195, 196, 0, 197, 198, 199, 208, 68, 69, - 70, 71, 72, 73, 0, 86, 87, 0, 238, 0, - 0, 0, 0, 62, 63, 0, 64, 65, 66, 67, - 0, 0, 0, 0, 209, 210, 200, 201, 202, 203, - 204, 205, 207, 206, 0, 0, 0, 0, 0, 0, - 0, 195, 196, 0, 197, 198, 199, 208, 209, 210, - 200, 201, 202, 203, 204, 205, 207, 206, 19, 20, - 21, 0, 17, 0, 138, 195, 196, 0, 197, 198, - 199, 208, 19, 20, 21, 0, 17, 0, 138, 0, - 19, 20, 21, 0, 17, 0, 236, 0, 0, 0, - 0, 0, 23, 26, 24, 25, 27, 14, 139, 15, - 169, 136, 137, 0, 0, 0, 23, 26, 24, 25, - 27, 14, 139, 15, 23, 26, 24, 25, 27, 14, - 0, 15, 0, 22, 19, 20, 21, 0, 17, 0, - 234, 0, 19, 20, 21, 0, 17, 22, 9, 0, - 43, 48, 0, 0, 45, 22, 44, 0, 52, 0, - 46, 47, 49, 50, 51, 54, 53, 0, 23, 26, - 24, 25, 27, 14, 0, 15, 23, 26, 24, 25, - 27, 14, 0, 15, 19, 20, 21, 166, 17, 0, - 138, 0, 0, 0, 45, 0, 44, 0, 52, 22, - 46, 47, 49, 50, 51, 54, 53, 22, 0, 0, - 19, 20, 21, 0, 0, 0, 183, 0, 23, 26, - 24, 25, 27, 0, 0, 0, 0, 31, 36, 0, - 0, 33, 0, 32, 0, 42, 0, 34, 35, 37, - 38, 39, 40, 41, 23, 26, 24, 25, 27, 22, - 43, 48, 58, 11, 45, 0, 44, 0, 52, 0, - 46, 47, 49, 50, 51, 54, 53, 0, 31, 36, - 55, 3, 33, 0, 32, 22, 42, 0, 34, 35, - 37, 38, 39, 40, 41, 33, 0, 32, 0, 42, - 0, 34, 35, 37, 38, 39, 40, 41, 0, 0, - 0, 0, 140, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 173, 176, 177, 178, 179, 180, - 181, 117, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, - 108, 109, 110, 111, 113, 112, 114, 115, 116, 120, - 118, 119, 91, 92, 93, 97, 0, 0, 0, 175, - 0, 0, 96, 94, 95, 99, 98, 100, 101, 102, - 103, 104, 105, 106, 91, 92, 93, 97, 0, 0, - 0, 0, 0, 0, 96, 94, 95, 99, 98, 100, - 101, 102, 103, 104, 105, 106, + 5, 90, 6, 89, 8, 194, 7, 88, 236, 2, + 57, 18, 229, 13, 84, 270, 198, 199, 56, 200, + 201, 202, 211, 60, 75, 76, 211, 77, 78, 79, + 80, 134, 80, 135, 67, 138, 273, 136, 200, 201, + 202, 211, 171, 175, 156, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 170, 170, 212, 213, + 203, 204, 205, 206, 207, 208, 210, 209, 269, 177, + 77, 78, 79, 80, 30, 198, 199, 29, 200, 201, + 202, 211, 281, 280, 196, 264, 195, 263, 185, 187, + 188, 189, 190, 191, 192, 285, 193, 262, 277, 171, + 214, 215, 216, 75, 76, 261, 77, 78, 79, 80, + 284, 212, 213, 203, 204, 205, 206, 207, 208, 210, + 209, 62, 63, 220, 64, 65, 66, 67, 198, 199, + 276, 200, 201, 202, 211, 64, 65, 66, 67, 291, + 243, 275, 233, 224, 225, 226, 227, 203, 204, 205, + 206, 207, 208, 210, 209, 234, 290, 243, 233, 274, + 221, 222, 198, 199, 223, 200, 201, 202, 211, 173, + 271, 272, 134, 17, 135, 157, 138, 174, 136, 242, + 243, 287, 286, 238, 235, 232, 231, 240, 68, 69, + 70, 71, 72, 73, 178, 144, 132, 131, 130, 129, + 234, 128, 127, 75, 76, 82, 77, 78, 79, 80, + 230, 268, 81, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 62, + 63, 74, 64, 65, 66, 67, 266, 265, 57, 219, + 57, 218, 217, 61, 28, 279, 228, 278, 240, 59, + 16, 60, 4, 60, 212, 213, 203, 204, 205, 206, + 207, 208, 210, 209, 124, 125, 126, 133, 12, 10, + 137, 198, 199, 1, 200, 201, 202, 211, 134, 0, + 135, 283, 138, 0, 136, 282, 0, 0, 196, 196, + 195, 195, 288, 289, 91, 92, 93, 97, 120, 0, + 83, 85, 0, 0, 96, 94, 95, 99, 98, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 113, 112, 114, 115, 116, 117, 118, 119, 123, + 121, 122, 0, 68, 69, 70, 71, 72, 73, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, + 267, 64, 65, 66, 67, 91, 92, 93, 97, 120, + 0, 0, 85, 86, 87, 96, 94, 95, 99, 98, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 113, 112, 114, 115, 116, 117, 118, 119, + 123, 121, 122, 212, 213, 203, 204, 205, 206, 207, + 208, 210, 209, 260, 0, 0, 0, 0, 0, 0, + 198, 199, 0, 200, 201, 202, 211, 0, 0, 0, + 0, 0, 43, 48, 86, 87, 45, 241, 44, 0, + 52, 0, 46, 47, 49, 50, 51, 54, 53, 0, + 0, 0, 0, 0, 0, 0, 212, 213, 203, 204, + 205, 206, 207, 208, 210, 209, 197, 0, 0, 0, + 0, 0, 0, 198, 199, 0, 200, 201, 202, 211, + 212, 213, 203, 204, 205, 206, 207, 208, 210, 209, + 175, 0, 0, 0, 0, 0, 0, 198, 199, 0, + 200, 201, 202, 211, 19, 20, 21, 0, 17, 0, + 141, 212, 213, 203, 204, 205, 206, 207, 208, 210, + 209, 19, 20, 21, 0, 17, 0, 141, 198, 199, + 0, 200, 201, 202, 211, 68, 69, 70, 71, 72, + 73, 23, 26, 24, 25, 27, 14, 142, 15, 0, + 75, 76, 0, 77, 78, 79, 80, 0, 23, 26, + 24, 25, 27, 14, 142, 15, 0, 139, 140, 19, + 20, 21, 22, 17, 0, 239, 0, 19, 20, 21, + 0, 17, 0, 237, 0, 0, 19, 20, 21, 22, + 17, 45, 9, 44, 0, 52, 0, 46, 47, 49, + 50, 51, 54, 53, 172, 0, 23, 26, 24, 25, + 27, 14, 0, 15, 23, 26, 24, 25, 27, 14, + 0, 15, 0, 23, 26, 24, 25, 27, 14, 0, + 15, 169, 19, 20, 21, 0, 17, 22, 141, 0, + 0, 0, 0, 0, 0, 22, 0, 43, 48, 0, + 0, 45, 0, 44, 22, 52, 0, 46, 47, 49, + 50, 51, 54, 53, 0, 0, 0, 0, 0, 23, + 26, 24, 25, 27, 31, 36, 58, 11, 33, 0, + 32, 0, 42, 0, 34, 35, 37, 38, 39, 40, + 41, 19, 20, 21, 0, 31, 36, 186, 0, 33, + 22, 32, 0, 42, 0, 34, 35, 37, 38, 39, + 40, 41, 33, 0, 32, 0, 42, 0, 34, 35, + 37, 38, 39, 40, 41, 0, 0, 0, 23, 26, + 24, 25, 27, 0, 0, 0, 0, 0, 176, 179, + 180, 181, 182, 183, 184, 120, 0, 55, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, + 0, 0, 0, 107, 108, 109, 110, 111, 113, 112, + 114, 115, 116, 117, 118, 119, 123, 121, 122, 143, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 91, 92, 93, 97, 0, 0, 0, 178, 0, + 0, 96, 94, 95, 99, 98, 100, 101, 102, 103, + 104, 105, 106, 91, 92, 93, 97, 0, 0, 0, + 0, 0, 0, 96, 94, 95, 99, 98, 100, 101, + 102, 103, 104, 105, 106, } var yyPact = [...]int{ - 536, -17, -22, 615, -1000, 597, -1000, -1000, -1000, 536, - -1000, 353, -1000, 91, 234, 231, -1000, 286, -1000, -1000, - -1000, -1000, 329, 229, 228, 227, 226, 224, -1000, 222, - 462, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 574, 19, 497, 191, 121, - 62, 747, 214, 214, 214, 214, 214, 214, -1000, -1000, - -1000, -1000, -1000, -1000, 604, 604, 604, 604, 604, 604, - 604, 344, 712, -1000, 198, 344, 344, 344, -1000, -1000, + 570, 23, 19, 629, -1000, 366, -1000, -1000, -1000, 570, + -1000, 275, -1000, 130, 200, 193, -1000, 289, -1000, -1000, + -1000, -1000, 258, 190, 189, 187, 186, 185, -1000, 184, + 505, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 163, 608, 44, 581, 156, 164, + 467, 776, 182, 182, 182, 182, 182, 182, -1000, -1000, + -1000, -1000, -1000, -1000, 675, 675, 675, 675, 675, 675, + 675, 350, 726, -1000, 445, 350, 350, 350, -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, 292, 276, 266, - 245, -1000, -1000, -1000, 112, 344, 344, 344, 344, 140, - -1000, 597, -1000, -1000, -1000, -1000, 171, 156, 578, 151, - 628, 528, -1000, -1000, -1000, -1000, 628, -1000, -1000, -1000, - -1000, -1000, -1000, 537, 162, -1000, -1000, -1000, -1000, 537, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 476, -1000, - -1000, -1000, -1000, 125, -1000, 484, 103, 103, -57, -57, - -57, -57, 83, 604, 7, 7, -59, -59, -59, -59, - 405, 168, -1000, -1000, -1000, 344, 344, 344, 344, 344, - 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, - 344, 381, -35, -35, 37, 24, 22, -5, 259, 243, - -1000, 331, 132, 53, 3, 117, -1000, -27, 92, 86, - 497, 157, 54, 16, 528, -1000, 484, -32, -1000, -1000, - 712, -35, -35, -61, -61, -61, -49, -49, -49, -49, - -49, -49, -49, -49, -61, 272, 272, -1000, -1000, -1000, - -1000, -1000, -6, -12, -1000, -1000, -1000, -1000, -1000, 140, - 769, 50, 42, -1000, 476, -1000, -1000, -1000, -1000, -1000, - -1000, 148, 104, 712, 712, 90, 84, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 238, 237, 235, 119, -1000, -1000, -1000, 151, 350, 350, + 350, 350, 206, -1000, 366, -1000, -1000, -1000, -1000, 174, + 173, 616, 172, 642, 561, -1000, -1000, -1000, -1000, 642, + -1000, -1000, -1000, -1000, -1000, -1000, 521, 163, -1000, -1000, + -1000, -1000, 521, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 488, -1000, -1000, -1000, -1000, 48, -1000, 553, 59, + 59, -45, -45, -45, -45, -49, 675, -6, -6, -47, + -47, -47, -47, 414, 166, -1000, -1000, -1000, 350, 350, + 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, + 350, 350, 350, 350, 390, -38, -38, 54, 46, 36, + 34, 233, 232, -1000, 337, 198, 55, 2, 157, -1000, + -22, 146, 128, 581, 30, 117, 43, 561, -1000, 553, + -13, -1000, -1000, 726, -38, -38, -53, -53, -53, -57, + -57, -57, -57, -57, -57, -57, -57, -53, 89, 89, + -1000, -1000, -1000, -1000, -1000, 32, 31, -1000, -1000, -1000, + -1000, -1000, 206, 798, 62, 47, -1000, 488, -1000, -1000, + -1000, -1000, -1000, -1000, 170, 169, 726, 726, 143, 126, + -1000, -1000, } var yyPgo = [...]int{ - 0, 396, 6, 395, 4, 5, 0, 670, 355, 8, - 354, 2, 326, 341, 340, 652, 13, 339, 300, 11, - 14, 7, 3, 1, 12, 299, 276, + 0, 273, 6, 270, 4, 5, 0, 737, 269, 8, + 268, 2, 231, 267, 252, 666, 13, 250, 249, 11, + 14, 7, 3, 1, 12, 246, 244, } var yyR1 = [...]int{ @@ -361,8 +371,8 @@ var yyR1 = [...]int{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, - 23, 23, 23, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, } var yyR2 = [...]int{ @@ -380,40 +390,41 @@ var yyR2 = [...]int{ 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, + 3, 3, 3, 3, 4, 4, } var yyChk = [...]int{ -1000, -1, -9, -7, -14, -6, -11, -2, -4, 12, - -8, -15, -10, -16, 45, 47, -17, 10, -19, 6, - 7, 8, 71, 40, 42, 43, 41, 44, -26, 51, - 52, 53, 59, 57, 63, 64, 54, 65, 66, 67, - 68, 69, 61, 53, 59, 57, 63, 64, 54, 65, - 66, 67, 61, 69, 68, -7, -9, -6, -15, -18, - -16, -12, 70, 71, 73, 74, 75, 76, 55, 56, - 57, 58, 59, 60, -12, 70, 71, 73, 74, 75, - 76, 12, 12, 11, -20, 12, 71, 72, -21, -22, + -8, -15, -10, -16, 48, 50, -17, 10, -19, 6, + 7, 8, 74, 43, 45, 46, 44, 47, -26, 54, + 55, 56, 62, 60, 66, 67, 57, 68, 69, 70, + 71, 72, 64, 56, 62, 60, 66, 67, 57, 68, + 69, 70, 64, 72, 71, -7, -9, -6, -15, -18, + -16, -12, 73, 74, 76, 77, 78, 79, 58, 59, + 60, 61, 62, 63, -12, 73, 74, 76, 77, 78, + 79, 12, 12, 11, -20, 12, 74, 75, -21, -22, -23, 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, 12, - -13, -6, -11, -2, -3, -4, 49, 50, 12, 46, - -7, 12, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -6, 12, -6, -6, -6, -6, -6, - -6, -6, -6, -6, -6, -6, 13, 13, 52, 13, - 13, 13, 13, -15, -21, 12, -15, -15, -15, -15, - -15, -15, -16, 12, -16, -16, -16, -16, -16, -16, - -20, -5, -22, -23, 11, 70, 71, 73, 74, 75, - 55, 56, 57, 58, 59, 60, 62, 61, 76, 53, - 54, -20, -20, -20, 4, 4, 4, 4, 38, 39, - 13, -20, -20, -20, -20, -25, -24, 4, 12, 12, - -6, -16, 12, -9, 12, -19, 12, -9, 13, 13, - 14, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, 13, 48, 48, - 48, 48, 4, 4, 13, 13, 13, 13, 13, 14, - 55, 13, 13, 13, 52, -22, -23, 48, 48, -24, - -21, 45, 45, 12, 12, -5, -5, 13, 13, + 30, 31, 33, 32, 34, 35, 36, 37, 38, 39, + 9, 41, 42, 40, 6, 7, 8, 12, 12, 12, + 12, 12, 12, -13, -6, -11, -2, -3, -4, 52, + 53, 12, 49, -7, 12, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -6, 12, -6, -6, + -6, -6, -6, -6, -6, -6, -6, -6, -6, 13, + 13, 55, 13, 13, 13, 13, -15, -21, 12, -15, + -15, -15, -15, -15, -15, -16, 12, -16, -16, -16, + -16, -16, -16, -20, -5, -22, -23, 11, 73, 74, + 76, 77, 78, 58, 59, 60, 61, 62, 63, 65, + 64, 79, 56, 57, -20, -20, -20, 4, 4, 4, + 4, 41, 42, 13, -20, -20, -20, -20, -25, -24, + 4, 12, 12, -6, -16, 12, -9, 12, -19, 12, + -9, 13, 13, 14, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + 13, 51, 51, 51, 51, 4, 4, 13, 13, 13, + 13, 13, 14, 58, 13, 13, 13, 55, -22, -23, + 51, 51, -24, -21, 48, 48, 12, 12, -5, -5, + 13, 13, } var yyDef = [...]int{ @@ -428,24 +439,25 @@ var yyDef = [...]int{ 0, 0, 0, 51, 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 0, 0, 0, - 0, 83, 84, 85, 0, 0, 0, 0, 0, 0, - 4, 25, 26, 27, 28, 29, 0, 0, 0, 0, - 7, 0, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 38, 0, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 6, 20, 0, 37, - 62, 70, 72, 60, 61, 0, 63, 64, 65, 66, - 67, 68, 53, 0, 73, 74, 75, 76, 77, 78, - 0, 0, 33, 34, 52, 0, 0, 0, 0, 0, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 0, 0, 0, 0, 83, 84, 85, 0, 0, 0, + 0, 0, 0, 4, 25, 26, 27, 28, 29, 0, + 0, 0, 0, 7, 0, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 38, 0, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 6, + 20, 0, 37, 62, 70, 72, 60, 61, 0, 63, + 64, 65, 66, 67, 68, 53, 0, 73, 74, 75, + 76, 77, 78, 0, 0, 33, 34, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 116, 117, 0, 0, 0, 0, 0, 0, - 86, 0, 0, 0, 0, 0, 97, 0, 0, 0, - 0, 0, 0, 0, 0, -2, 0, 0, 30, 32, - 0, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 99, 147, 148, - 149, 150, 0, 0, 87, 88, 89, 90, 96, 0, - 0, 91, 92, 31, 0, 35, 36, 151, 152, 98, - 95, 0, 0, 0, 0, 0, 0, 93, 94, + 0, 0, 0, 0, 0, 116, 117, 0, 0, 0, + 0, 0, 0, 86, 0, 0, 0, 0, 0, 97, + 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, + 0, 30, 32, 0, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 99, 150, 151, 152, 153, 0, 0, 87, 88, 89, + 90, 96, 0, 0, 91, 92, 31, 0, 35, 36, + 154, 155, 98, 95, 0, 0, 0, 0, 0, 0, + 93, 94, } var yyTok1 = [...]int{ @@ -460,7 +472,7 @@ var yyTok2 = [...]int{ 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, 70, 71, - 72, 73, 74, 75, 76, + 72, 73, 74, 75, 76, 77, 78, 79, } var yyTok3 = [...]int{ 0, @@ -1680,38 +1692,56 @@ yydefault: yyVAL.intrinsicField = NewIntrinsic(IntrinsicTraceDuration) } case 147: + yyDollar = yyS[yypt-1 : yypt+1] +//line pkg/traceql/expr.y:348 + { + yyVAL.intrinsicField = NewIntrinsic(IntrinsicNestedSetLeft) + } + case 148: + yyDollar = yyS[yypt-1 : yypt+1] +//line pkg/traceql/expr.y:349 + { + yyVAL.intrinsicField = NewIntrinsic(IntrinsicNestedSetRight) + } + case 149: + yyDollar = yyS[yypt-1 : yypt+1] +//line pkg/traceql/expr.y:350 + { + yyVAL.intrinsicField = NewIntrinsic(IntrinsicNestedSetParent) + } + case 150: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:351 +//line pkg/traceql/expr.y:354 { yyVAL.attributeField = NewAttribute(yyDollar[2].staticStr) } - case 148: + case 151: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:352 +//line pkg/traceql/expr.y:355 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, false, yyDollar[2].staticStr) } - case 149: + case 152: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:353 +//line pkg/traceql/expr.y:356 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, false, yyDollar[2].staticStr) } - case 150: + case 153: yyDollar = yyS[yypt-3 : yypt+1] -//line pkg/traceql/expr.y:354 +//line pkg/traceql/expr.y:357 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeNone, true, yyDollar[2].staticStr) } - case 151: + case 154: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:355 +//line pkg/traceql/expr.y:358 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeResource, true, yyDollar[3].staticStr) } - case 152: + case 155: yyDollar = yyS[yypt-4 : yypt+1] -//line pkg/traceql/expr.y:356 +//line pkg/traceql/expr.y:359 { yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, true, yyDollar[3].staticStr) } diff --git a/pkg/traceql/lexer.go b/pkg/traceql/lexer.go index 81dc235a5fb..df98c74e1e0 100644 --- a/pkg/traceql/lexer.go +++ b/pkg/traceql/lexer.go @@ -66,6 +66,9 @@ var tokens = map[string]int{ "rootName": ROOTNAME, "rootServiceName": ROOTSERVICENAME, "traceDuration": TRACEDURATION, + "nestedSetLeft": NESTEDSETLEFT, + "nestedSetRight": NESTEDSETRIGHT, + "nestedSetParent": NESTEDSETPARENT, "parent": PARENT, "parent.": PARENT_DOT, "resource.": RESOURCE_DOT, @@ -185,7 +188,6 @@ func (l *lexer) Lex(lval *yySymType) int { l.Next() continue } - break } diff --git a/pkg/traceql/lexer_test.go b/pkg/traceql/lexer_test.go index c6f465e4980..8b2f92aa7df 100644 --- a/pkg/traceql/lexer_test.go +++ b/pkg/traceql/lexer_test.go @@ -69,6 +69,11 @@ func TestLexerAttributes(t *testing.T) { {`.24h`, []int{DURATION}}, })) } +func TestLexerIntrinsics(t *testing.T) { + testLexer(t, ([]lexerTestCase{ + {`nestedSetLeft`, []int{NESTEDSETLEFT}}, + })) +} func TestLexerMultitokens(t *testing.T) { testLexer(t, ([]lexerTestCase{ diff --git a/pkg/traceql/parse_test.go b/pkg/traceql/parse_test.go index aabd815343e..2c043605c85 100644 --- a/pkg/traceql/parse_test.go +++ b/pkg/traceql/parse_test.go @@ -979,6 +979,9 @@ func TestIntrinsics(t *testing.T) { {in: "traceDuration", expected: IntrinsicTraceDuration}, {in: "rootServiceName", expected: IntrinsicTraceRootService}, {in: "rootName", expected: IntrinsicTraceRootSpan}, + {in: "nestedSetLeft", expected: IntrinsicNestedSetLeft}, + {in: "nestedSetRight", expected: IntrinsicNestedSetRight}, + {in: "nestedSetParent", expected: IntrinsicNestedSetParent}, } for _, tc := range tests { diff --git a/tempodb/encoding/vparquet3/block_autocomplete.go b/tempodb/encoding/vparquet3/block_autocomplete.go index 1f010633636..06d6030e76c 100644 --- a/tempodb/encoding/vparquet3/block_autocomplete.go +++ b/tempodb/encoding/vparquet3/block_autocomplete.go @@ -209,7 +209,11 @@ func createDistinctSpanIterator( // TODO: Support structural operators case traceql.IntrinsicStructuralDescendant, traceql.IntrinsicStructuralChild, - traceql.IntrinsicStructuralSibling: + traceql.IntrinsicStructuralSibling, + // nested set intrinsics should not be considered when autocompleting + traceql.IntrinsicNestedSetLeft, + traceql.IntrinsicNestedSetRight, + traceql.IntrinsicNestedSetParent: continue } diff --git a/tempodb/encoding/vparquet3/block_traceql.go b/tempodb/encoding/vparquet3/block_traceql.go index ecd39e68d04..3d57f48e59c 100644 --- a/tempodb/encoding/vparquet3/block_traceql.go +++ b/tempodb/encoding/vparquet3/block_traceql.go @@ -57,6 +57,7 @@ type span struct { cbSpanset *traceql.Spanset } +// jpe - all attributes needs to return nested set info now? func (s *span) AllAttributes() map[traceql.Attribute]traceql.Static { atts := make(map[traceql.Attribute]traceql.Static, len(s.spanAttrs)+len(s.resourceAttrs)+len(s.traceAttrs)) for _, st := range s.traceAttrs { @@ -77,6 +78,15 @@ func (s *span) AllAttributes() map[traceql.Attribute]traceql.Static { } atts[st.a] = st.s } + if s.nestedSetLeft > 0 { + atts[traceql.NewIntrinsic(traceql.IntrinsicNestedSetLeft)] = traceql.Static{Type: traceql.TypeInt, N: int(s.nestedSetLeft)} + } + if s.nestedSetRight > 0 { + atts[traceql.NewIntrinsic(traceql.IntrinsicNestedSetRight)] = traceql.Static{Type: traceql.TypeInt, N: int(s.nestedSetRight)} + } + if s.nestedSetParent != 0 { + atts[traceql.NewIntrinsic(traceql.IntrinsicNestedSetParent)] = traceql.Static{Type: traceql.TypeInt, N: int(s.nestedSetParent)} + } return atts } @@ -141,6 +151,16 @@ func (s *span) AttributeFor(a traceql.Attribute) (traceql.Static, bool) { } if a.Intrinsic != traceql.IntrinsicNone { + if a.Intrinsic == traceql.IntrinsicNestedSetLeft { + return traceql.Static{Type: traceql.TypeInt, N: int(s.nestedSetLeft)}, true + } + if a.Intrinsic == traceql.IntrinsicNestedSetRight { + return traceql.Static{Type: traceql.TypeInt, N: int(s.nestedSetRight)}, true + } + if a.Intrinsic == traceql.IntrinsicNestedSetParent { + return traceql.Static{Type: traceql.TypeInt, N: int(s.nestedSetParent)}, true + } + // intrinsics are always on the span or trace ... for now if attr := find(a, s.spanAttrs); attr != nil { return *attr, true @@ -149,7 +169,6 @@ func (s *span) AttributeFor(a traceql.Attribute) (traceql.Static, bool) { if attr := find(a, s.traceAttrs); attr != nil { return *attr, true } - } // name search in span and then resource to give precedence to span @@ -511,6 +530,9 @@ var intrinsicColumnLookups = map[traceql.Intrinsic]struct { traceql.IntrinsicStructuralDescendant: {intrinsicScopeSpan, traceql.TypeNil, ""}, // Not a real column, this entry is only used to assign default scope. traceql.IntrinsicStructuralChild: {intrinsicScopeSpan, traceql.TypeNil, ""}, // Not a real column, this entry is only used to assign default scope. traceql.IntrinsicStructuralSibling: {intrinsicScopeSpan, traceql.TypeNil, ""}, // Not a real column, this entry is only used to assign default scope. + traceql.IntrinsicNestedSetLeft: {intrinsicScopeSpan, traceql.TypeInt, columnPathSpanNestedSetLeft}, + traceql.IntrinsicNestedSetRight: {intrinsicScopeSpan, traceql.TypeInt, columnPathSpanNestedSetRight}, + traceql.IntrinsicNestedSetParent: {intrinsicScopeSpan, traceql.TypeInt, columnPathSpanParentID}, traceql.IntrinsicTraceRootService: {intrinsicScopeTrace, traceql.TypeString, columnPathRootServiceName}, traceql.IntrinsicTraceRootSpan: {intrinsicScopeTrace, traceql.TypeString, columnPathRootSpanName}, @@ -1209,6 +1231,32 @@ func createSpanIterator(makeIter makeIterFn, primaryIter parquetquery.Iterator, case traceql.IntrinsicStructuralSibling: selectColumnIfNotAlready(columnPathSpanParentID) continue + + case traceql.IntrinsicNestedSetLeft: + pred, err := createIntPredicate(cond.Op, cond.Operands) + if err != nil { + return nil, err + } + addPredicate(columnPathSpanNestedSetLeft, pred) + columnSelectAs[columnPathSpanNestedSetLeft] = columnPathSpanNestedSetLeft + continue + case traceql.IntrinsicNestedSetRight: + pred, err := createIntPredicate(cond.Op, cond.Operands) + if err != nil { + return nil, err + } + addPredicate(columnPathSpanNestedSetRight, pred) + columnSelectAs[columnPathSpanNestedSetRight] = columnPathSpanNestedSetRight + continue + case traceql.IntrinsicNestedSetParent: + pred, err := createIntPredicate(cond.Op, cond.Operands) + if err != nil { + return nil, err + } + addPredicate(columnPathSpanParentID, pred) + columnSelectAs[columnPathSpanParentID] = columnPathSpanParentID + continue + } // Well-known attribute? From 320f078c8d56352ecea8d387fd45807898491ece Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Fri, 15 Mar 2024 15:13:06 -0400 Subject: [PATCH 2/7] only return nested set params if explicitly requested Signed-off-by: Joe Elliott --- tempodb/encoding/vparquet3/block_traceql.go | 45 +++++++++++++-------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/tempodb/encoding/vparquet3/block_traceql.go b/tempodb/encoding/vparquet3/block_traceql.go index 3d57f48e59c..9b5497d5bbd 100644 --- a/tempodb/encoding/vparquet3/block_traceql.go +++ b/tempodb/encoding/vparquet3/block_traceql.go @@ -57,7 +57,6 @@ type span struct { cbSpanset *traceql.Spanset } -// jpe - all attributes needs to return nested set info now? func (s *span) AllAttributes() map[traceql.Attribute]traceql.Static { atts := make(map[traceql.Attribute]traceql.Static, len(s.spanAttrs)+len(s.resourceAttrs)+len(s.traceAttrs)) for _, st := range s.traceAttrs { @@ -78,15 +77,6 @@ func (s *span) AllAttributes() map[traceql.Attribute]traceql.Static { } atts[st.a] = st.s } - if s.nestedSetLeft > 0 { - atts[traceql.NewIntrinsic(traceql.IntrinsicNestedSetLeft)] = traceql.Static{Type: traceql.TypeInt, N: int(s.nestedSetLeft)} - } - if s.nestedSetRight > 0 { - atts[traceql.NewIntrinsic(traceql.IntrinsicNestedSetRight)] = traceql.Static{Type: traceql.TypeInt, N: int(s.nestedSetRight)} - } - if s.nestedSetParent != 0 { - atts[traceql.NewIntrinsic(traceql.IntrinsicNestedSetParent)] = traceql.Static{Type: traceql.TypeInt, N: int(s.nestedSetParent)} - } return atts } @@ -1135,11 +1125,14 @@ func createAllIterator(ctx context.Context, primaryIter parquetquery.Iterator, c // one span each. Spans are returned that match any of the given conditions. func createSpanIterator(makeIter makeIterFn, primaryIter parquetquery.Iterator, conditions []traceql.Condition, requireAtLeastOneMatch, allConditions bool, dedicatedColumns backend.DedicatedColumns) (parquetquery.Iterator, error) { var ( - columnSelectAs = map[string]string{} - columnPredicates = map[string][]parquetquery.Predicate{} - iters []parquetquery.Iterator - genericConditions []traceql.Condition - columnMapping = dedicatedColumnsToColumnMapping(dedicatedColumns, backend.DedicatedColumnScopeSpan) + columnSelectAs = map[string]string{} + columnPredicates = map[string][]parquetquery.Predicate{} + iters []parquetquery.Iterator + genericConditions []traceql.Condition + columnMapping = dedicatedColumnsToColumnMapping(dedicatedColumns, backend.DedicatedColumnScopeSpan) + nestedSetLeftExplicit = false + nestedSetRightExplicit = false + nestedSetParentExplicit = false ) addPredicate := func(columnPath string, p parquetquery.Predicate) { @@ -1233,6 +1226,7 @@ func createSpanIterator(makeIter makeIterFn, primaryIter parquetquery.Iterator, continue case traceql.IntrinsicNestedSetLeft: + nestedSetLeftExplicit = true pred, err := createIntPredicate(cond.Op, cond.Operands) if err != nil { return nil, err @@ -1241,6 +1235,7 @@ func createSpanIterator(makeIter makeIterFn, primaryIter parquetquery.Iterator, columnSelectAs[columnPathSpanNestedSetLeft] = columnPathSpanNestedSetLeft continue case traceql.IntrinsicNestedSetRight: + nestedSetRightExplicit = true pred, err := createIntPredicate(cond.Op, cond.Operands) if err != nil { return nil, err @@ -1249,6 +1244,7 @@ func createSpanIterator(makeIter makeIterFn, primaryIter parquetquery.Iterator, columnSelectAs[columnPathSpanNestedSetRight] = columnPathSpanNestedSetRight continue case traceql.IntrinsicNestedSetParent: + nestedSetParentExplicit = true pred, err := createIntPredicate(cond.Op, cond.Operands) if err != nil { return nil, err @@ -1334,8 +1330,12 @@ func createSpanIterator(makeIter makeIterFn, primaryIter parquetquery.Iterator, } minCount = len(distinct) } + spanCol := &spanCollector{ - minAttributes: minCount, + minAttributes: minCount, + nestedSetLeftExplicit: nestedSetLeftExplicit, + nestedSetRightExplicit: nestedSetRightExplicit, + nestedSetParentExplicit: nestedSetParentExplicit, } // This is an optimization for when all of the span conditions must be met. @@ -1877,6 +1877,10 @@ func createAttributeIterator(makeIter makeIterFn, conditions []traceql.Condition // This turns groups of span values into Span objects type spanCollector struct { minAttributes int + + nestedSetLeftExplicit bool + nestedSetRightExplicit bool + nestedSetParentExplicit bool } var _ parquetquery.GroupPredicate = (*spanCollector)(nil) @@ -1960,10 +1964,19 @@ func (c *spanCollector) KeepGroup(res *parquetquery.IteratorResult) bool { sp.addSpanAttr(traceql.IntrinsicKindAttribute, traceql.NewStaticKind(kind)) case columnPathSpanParentID: sp.nestedSetParent = kv.Value.Int32() + if c.nestedSetParentExplicit { + sp.addSpanAttr(traceql.IntrinsicNestedSetParentAttribute, traceql.NewStaticInt(int(kv.Value.Int32()))) + } case columnPathSpanNestedSetLeft: sp.nestedSetLeft = kv.Value.Int32() + if c.nestedSetLeftExplicit { + sp.addSpanAttr(traceql.IntrinsicNestedSetLeftAttribute, traceql.NewStaticInt(int(kv.Value.Int32()))) + } case columnPathSpanNestedSetRight: sp.nestedSetRight = kv.Value.Int32() + if c.nestedSetRightExplicit { + sp.addSpanAttr(traceql.IntrinsicNestedSetRightAttribute, traceql.NewStaticInt(int(kv.Value.Int32()))) + } default: // TODO - This exists for span-level dedicated columns like http.status_code // Are nils possible here? From 03bb60e85cf86b2d6cee0575f466c79de38cdee3 Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Fri, 15 Mar 2024 15:44:23 -0400 Subject: [PATCH 3/7] tests, tests, tests ! Signed-off-by: Joe Elliott --- pkg/traceql/ast_conditions_test.go | 49 +++++++++++ pkg/traceql/lexer_test.go | 2 + pkg/traceql/test_examples.yaml | 7 ++ tempodb/tempodb_search_test.go | 132 +++++++++++++++++++++++++++++ 4 files changed, 190 insertions(+) diff --git a/pkg/traceql/ast_conditions_test.go b/pkg/traceql/ast_conditions_test.go index 2f3eb15d272..fc828f3990b 100644 --- a/pkg/traceql/ast_conditions_test.go +++ b/pkg/traceql/ast_conditions_test.go @@ -150,6 +150,55 @@ func TestScalarFilter_extractConditions(t *testing.T) { } } +func TestStructuralNestedSet_extractConditions(t *testing.T) { + tests := []struct { + query string + conditions []Condition + allConditions bool + }{ + { + query: `{} >> {}`, + conditions: []Condition{ + newCondition(NewIntrinsic(IntrinsicStructuralDescendant), OpNone), + }, + allConditions: false, + }, + { + query: `{ nestedSetRight = 2 }`, + conditions: []Condition{ + newCondition(NewIntrinsic(IntrinsicNestedSetRight), OpEqual, NewStaticInt(2)), + }, + allConditions: true, + }, + + { + query: `{ nestedSetParent = 1 } > { nestedSetLeft < 3 }`, + conditions: []Condition{ + newCondition(NewIntrinsic(IntrinsicStructuralChild), OpNone), + newCondition(NewIntrinsic(IntrinsicNestedSetParent), OpEqual, NewStaticInt(1)), + newCondition(NewIntrinsic(IntrinsicNestedSetLeft), OpLess, NewStaticInt(3)), + }, + 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.Nil(t, req.SecondPassConditions) + assert.Equal(t, tt.allConditions, req.AllConditions, "FetchSpansRequest.AllConditions") + }) + } +} + func TestSelect_extractConditions(t *testing.T) { tests := []struct { query string diff --git a/pkg/traceql/lexer_test.go b/pkg/traceql/lexer_test.go index 8b2f92aa7df..0f510192933 100644 --- a/pkg/traceql/lexer_test.go +++ b/pkg/traceql/lexer_test.go @@ -72,6 +72,8 @@ func TestLexerAttributes(t *testing.T) { func TestLexerIntrinsics(t *testing.T) { testLexer(t, ([]lexerTestCase{ {`nestedSetLeft`, []int{NESTEDSETLEFT}}, + {`nestedSetRight`, []int{NESTEDSETRIGHT}}, + {`duration`, []int{IDURATION}}, })) } diff --git a/pkg/traceql/test_examples.yaml b/pkg/traceql/test_examples.yaml index 75e3c7e45d7..ac37c338ff0 100644 --- a/pkg/traceql/test_examples.yaml +++ b/pkg/traceql/test_examples.yaml @@ -117,6 +117,9 @@ valid: - '{ true } | by(name) | count() > 2' - '{ true } | by(.field) | avg(.b) = 2' - '{ true } | by(3 * .field - 2) | max(duration) < 1s' + # undocumented - nested set + - '{ nestedSetLeft > 3 }' + - '{ } >> { kind = server } | select(nestedSetLeft, nestedSetRight, nestedSetParent)' # parse_fails throw an error when parsing parse_fails: @@ -234,6 +237,10 @@ validate_fails: # by - will *not* be valid when supported - group expressions must reference the span - '{ true } | by(1)' - '{ true } | by("foo")' + # nested set params are ints + - '{ nestedSetLeft = "foo" }' + - '{ nestedSetRight = false }' + - '{ nestedSetParent > "foo" }' # unsupported parse correctly and return an unsupported error when calling .validate() unsupported: diff --git a/tempodb/tempodb_search_test.go b/tempodb/tempodb_search_test.go index bf6283caf7c..501756c1853 100644 --- a/tempodb/tempodb_search_test.go +++ b/tempodb/tempodb_search_test.go @@ -32,6 +32,8 @@ import ( "github.com/grafana/tempo/tempodb/encoding" "github.com/grafana/tempo/tempodb/encoding/common" v2 "github.com/grafana/tempo/tempodb/encoding/v2" + "github.com/grafana/tempo/tempodb/encoding/vparquet" + "github.com/grafana/tempo/tempodb/encoding/vparquet2" "github.com/grafana/tempo/tempodb/wal" ) @@ -50,6 +52,7 @@ func TestSearchCompleteBlock(t *testing.T) { groupTraceQLRunner, traceQLStructural, traceQLExistence, + nestedSet, autoComplete, ) }) @@ -822,6 +825,135 @@ func traceQLStructural(t *testing.T, _ *tempopb.Trace, wantMeta *tempopb.TraceSe } } +func nestedSet(t *testing.T, _ *tempopb.Trace, wantMeta *tempopb.TraceSearchMetadata, _, _ []*tempopb.SearchRequest, meta *backend.BlockMeta, r Reader, _ common.BackendBlock) { + // nested set queries only supported in 3 or greater + if meta.Version == vparquet.VersionString || + meta.Version == vparquet2.VersionString { + return + } + + ctx := context.Background() + e := traceql.NewEngine() + + type test struct { + req *tempopb.SearchRequest + expected []*tempopb.TraceSearchMetadata + } + + searchesThatMatch := []*test{ + { + req: &tempopb.SearchRequest{Query: "{ .parent } | select(nestedSetLeft)"}, + expected: []*tempopb.TraceSearchMetadata{ + { + SpanSets: []*tempopb.SpanSet{ + { + Spans: []*tempopb.Span{ + { + SpanID: "0000000000040506", + StartTimeUnixNano: 1000000000000, + DurationNanos: 2000000000, + Name: "", + Attributes: []*v1_common.KeyValue{ + {Key: "parent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_BoolValue{BoolValue: true}}}, + {Key: "nestedSetLeft", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 1}}}, + }, + }, + }, + Matched: 1, + }, + }, + }, + }, + }, + { + req: &tempopb.SearchRequest{Query: "{ name = `BrokenSpan` } | select(nestedSetRight, nestedSetLeft, nestedSetParent)"}, + expected: []*tempopb.TraceSearchMetadata{ + { + SpanSets: []*tempopb.SpanSet{ + { + Spans: []*tempopb.Span{ + { + SpanID: "0000000000000000", + StartTimeUnixNano: 1000000000000, + DurationNanos: 1000000000, + Name: "BrokenSpan", + Attributes: []*v1_common.KeyValue{ + {Key: "nestedSetRight", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 0}}}, + {Key: "nestedSetLeft", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 0}}}, + {Key: "nestedSetParent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 0}}}, + }, + }, + }, + Matched: 1, + }, + }, + }, + }, + }, + // fun way to get the root span + { + req: &tempopb.SearchRequest{Query: "{ nestedSetParent = -1 } | select(name)"}, + expected: []*tempopb.TraceSearchMetadata{ + { + SpanSets: []*tempopb.SpanSet{ + { + Spans: []*tempopb.Span{ + { + SpanID: "0000000000040506", + StartTimeUnixNano: 1000000000000, + DurationNanos: 2000000000, + Name: "RootSpan", + Attributes: []*v1_common.KeyValue{ + {Key: "nestedSetParent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: -1}}}, + }, + }, + }, + Matched: 1, + }, + }, + }, + }, + }, + } + + for _, tc := range searchesThatMatch { + fetcher := traceql.NewSpansetFetcherWrapper(func(ctx context.Context, req traceql.FetchSpansRequest) (traceql.FetchSpansResponse, error) { + return r.Fetch(ctx, meta, req, common.DefaultSearchOptions()) + }) + + res, err := e.ExecuteSearch(ctx, tc.req, fetcher) + if errors.Is(err, common.ErrUnsupported) { + continue + } + + require.NoError(t, err, "search request: %+v", tc) + + // copy the root stuff in directly, spansets defined in test cases above. + for _, ss := range tc.expected { + ss.DurationMs = wantMeta.DurationMs + ss.RootServiceName = wantMeta.RootServiceName + ss.RootTraceName = wantMeta.RootTraceName + ss.StartTimeUnixNano = wantMeta.StartTimeUnixNano + ss.TraceID = wantMeta.TraceID + } + + // the actual spanset is impossible to predict since it's chosen randomly from the Spansets slice + // so set it to nil here and just test the slice using the testcases above + for _, tr := range res.Traces { + tr.SpanSet = nil + + for _, ss := range tr.SpanSets { + sort.Slice(ss.Attributes, func(i, j int) bool { + return ss.Attributes[i].Key < ss.Attributes[j].Key + }) + } + } + + require.NotNil(t, res, "search request: %v", tc) + require.Equal(t, tc.expected, res.Traces, "search request:", tc.req) + } +} + // existence func traceQLExistence(t *testing.T, _ *tempopb.Trace, _ *tempopb.TraceSearchMetadata, _, _ []*tempopb.SearchRequest, meta *backend.BlockMeta, r Reader, _ common.BackendBlock) { ctx := context.Background() From e23f963e2f4247fa04abe28be249fdbb6e5378b5 Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Fri, 15 Mar 2024 15:50:52 -0400 Subject: [PATCH 4/7] lint Signed-off-by: Joe Elliott --- pkg/traceql/lexer_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/traceql/lexer_test.go b/pkg/traceql/lexer_test.go index 0f510192933..e0f5fe61010 100644 --- a/pkg/traceql/lexer_test.go +++ b/pkg/traceql/lexer_test.go @@ -69,6 +69,7 @@ func TestLexerAttributes(t *testing.T) { {`.24h`, []int{DURATION}}, })) } + func TestLexerIntrinsics(t *testing.T) { testLexer(t, ([]lexerTestCase{ {`nestedSetLeft`, []int{NESTEDSETLEFT}}, From 1f03aa4dc8104b5fe84e688fffbea375ed71f66a Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Fri, 15 Mar 2024 15:52:06 -0400 Subject: [PATCH 5/7] changelog Signed-off-by: Joe Elliott --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ce32bbadb0..71e8a807343 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * [CHANGE] Align metrics query time ranges to the step parameter [#3490](https://github.com/grafana/tempo/pull/3490) (@mdisibio) * [ENHANCEMENT] Add string interning to TraceQL queries [#3411](https://github.com/grafana/tempo/pull/3411) (@mapno) * [ENHANCEMENT] Add new (unsafe) query hints for metrics queries [#3396](https://github.com/grafana/tempo/pull/3396) (@mdisibio) +* [ENHANCEMENT] Add nestedSetLeft/Right/Parent instrinsics to TraceQL. [#3497](https://github.com/grafana/tempo/pull/3497) (@joe-elliott) * [BUGFIX] Fix metrics query results when filtering and rating on the same attribute [#3428](https://github.com/grafana/tempo/issues/3428) (@mdisibio) * [BUGFIX] Fix metrics query results when series contain empty strings or nil values [#3429](https://github.com/grafana/tempo/issues/3429) (@mdisibio) * [BUGFIX] Fix metrics query duration check, add per-tenant override for max metrics query duration [#3479](https://github.com/grafana/tempo/issues/3479) (@mdisibio) From f3a06097902a6d2cb8587622e6af63300cead205 Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Thu, 21 Mar 2024 08:20:25 -0400 Subject: [PATCH 6/7] added/fixed tests Signed-off-by: Joe Elliott --- tempodb/tempodb_search_test.go | 79 +++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/tempodb/tempodb_search_test.go b/tempodb/tempodb_search_test.go index 501756c1853..85f3182ff3e 100644 --- a/tempodb/tempodb_search_test.go +++ b/tempodb/tempodb_search_test.go @@ -854,8 +854,8 @@ func nestedSet(t *testing.T, _ *tempopb.Trace, wantMeta *tempopb.TraceSearchMeta DurationNanos: 2000000000, Name: "", Attributes: []*v1_common.KeyValue{ - {Key: "parent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_BoolValue{BoolValue: true}}}, {Key: "nestedSetLeft", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 1}}}, + {Key: "parent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_BoolValue{BoolValue: true}}}, }, }, }, @@ -878,9 +878,9 @@ func nestedSet(t *testing.T, _ *tempopb.Trace, wantMeta *tempopb.TraceSearchMeta DurationNanos: 1000000000, Name: "BrokenSpan", Attributes: []*v1_common.KeyValue{ - {Key: "nestedSetRight", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 0}}}, {Key: "nestedSetLeft", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 0}}}, {Key: "nestedSetParent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 0}}}, + {Key: "nestedSetRight", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 0}}}, }, }, }, @@ -914,6 +914,73 @@ func nestedSet(t *testing.T, _ *tempopb.Trace, wantMeta *tempopb.TraceSearchMeta }, }, }, + { + req: &tempopb.SearchRequest{Query: "{nestedSetParent = -1} > {} | select(name)"}, // should select every span except root and disconnected spans + expected: []*tempopb.TraceSearchMetadata{ + { + SpanSets: []*tempopb.SpanSet{ + { + Spans: []*tempopb.Span{ + { + SpanID: "0000000000010203", + StartTimeUnixNano: 1000000000000, + DurationNanos: 1000000000, + Name: "MySpan", + Attributes: []*v1_common.KeyValue{ + {Key: "nestedSetParent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 1}}}, + }, + }, + { + SpanID: "0000000000070809", + StartTimeUnixNano: 1000000000000, + DurationNanos: 1000000000, + Name: "", + Attributes: []*v1_common.KeyValue{ + {Key: "nestedSetParent", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 1}}}, + }, + }, + }, + Matched: 2, + }, + }, + }, + }, + }, + { + req: &tempopb.SearchRequest{Query: "{nestedSetLeft = 1} >> {} | select(name, nestedSetRight)"}, + expected: []*tempopb.TraceSearchMetadata{ + { + SpanSets: []*tempopb.SpanSet{ + { + Spans: []*tempopb.Span{ + { + SpanID: "0000000000010203", + StartTimeUnixNano: 1000000000000, + DurationNanos: 1000000000, + Name: "MySpan", + Attributes: []*v1_common.KeyValue{ + // including the nestedSetLeft value may be a bug, but this occurs for all attributes and not just nested set attributes + {Key: "nestedSetLeft", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 2}}}, + {Key: "nestedSetRight", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 3}}}, + }, + }, + { + SpanID: "0000000000070809", + StartTimeUnixNano: 1000000000000, + DurationNanos: 1000000000, + Name: "", + Attributes: []*v1_common.KeyValue{ + {Key: "nestedSetLeft", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 4}}}, + {Key: "nestedSetRight", Value: &v1_common.AnyValue{Value: &v1_common.AnyValue_IntValue{IntValue: 5}}}, + }, + }, + }, + Matched: 2, + }, + }, + }, + }, + }, } for _, tc := range searchesThatMatch { @@ -943,9 +1010,11 @@ func nestedSet(t *testing.T, _ *tempopb.Trace, wantMeta *tempopb.TraceSearchMeta tr.SpanSet = nil for _, ss := range tr.SpanSets { - sort.Slice(ss.Attributes, func(i, j int) bool { - return ss.Attributes[i].Key < ss.Attributes[j].Key - }) + for _, span := range ss.Spans { + sort.Slice(span.Attributes, func(i, j int) bool { + return span.Attributes[i].Key < span.Attributes[j].Key + }) + } } } From 104cf8df348b0574dedaefde5343c2674f1c7566 Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Thu, 21 Mar 2024 09:35:26 -0400 Subject: [PATCH 7/7] fix predicate adding Signed-off-by: Joe Elliott --- tempodb/encoding/vparquet3/block_traceql.go | 27 +++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/tempodb/encoding/vparquet3/block_traceql.go b/tempodb/encoding/vparquet3/block_traceql.go index 9b5497d5bbd..fb8b5b55f66 100644 --- a/tempodb/encoding/vparquet3/block_traceql.go +++ b/tempodb/encoding/vparquet3/block_traceql.go @@ -1135,12 +1135,25 @@ func createSpanIterator(makeIter makeIterFn, primaryIter parquetquery.Iterator, nestedSetParentExplicit = false ) + // todo: improve these methods. if addPredicate gets a nil predicate shouldn't it just wipe out the existing predicates instead of appending? + // nil predicate matches everything. what's the point of also evaluating a "real" predicate? addPredicate := func(columnPath string, p parquetquery.Predicate) { columnPredicates[columnPath] = append(columnPredicates[columnPath], p) } - selectColumnIfNotAlready := func(path string) { - if columnPredicates[path] == nil { + addNilPredicateIfNotAlready := func(path string) { + preds := columnPredicates[path] + foundOpNone := false + + // check to see if there is a nil predicate and only add if it doesn't exist + for _, pred := range preds { + if pred == nil { + foundOpNone = true + break + } + } + + if !foundOpNone { addPredicate(path, nil) columnSelectAs[path] = path } @@ -1212,17 +1225,17 @@ func createSpanIterator(makeIter makeIterFn, primaryIter parquetquery.Iterator, continue case traceql.IntrinsicStructuralDescendant: - selectColumnIfNotAlready(columnPathSpanNestedSetLeft) - selectColumnIfNotAlready(columnPathSpanNestedSetRight) + addNilPredicateIfNotAlready(columnPathSpanNestedSetLeft) + addNilPredicateIfNotAlready(columnPathSpanNestedSetRight) continue case traceql.IntrinsicStructuralChild: - selectColumnIfNotAlready(columnPathSpanNestedSetLeft) - selectColumnIfNotAlready(columnPathSpanParentID) + addNilPredicateIfNotAlready(columnPathSpanNestedSetLeft) + addNilPredicateIfNotAlready(columnPathSpanParentID) continue case traceql.IntrinsicStructuralSibling: - selectColumnIfNotAlready(columnPathSpanParentID) + addNilPredicateIfNotAlready(columnPathSpanParentID) continue case traceql.IntrinsicNestedSetLeft: