package v3 import ( "testing" . "github.com/smartystreets/goconvey/convey" "go.signoz.io/signoz/pkg/query-service/constants" v3 "go.signoz.io/signoz/pkg/query-service/model/v3" ) var buildFilterQueryData = []struct { Name string FilterSet *v3.FilterSet ExpectedFilter string }{ { Name: "Test attribute and resource attribute", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "user.name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "john", Operator: "="}, {Key: v3.AttributeKey{Key: "k8s_namespace", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource}, Value: "my_service", Operator: "!="}, }}, ExpectedFilter: " AND stringTagMap['user.name'] = 'john' AND resourceTagsMap['k8s_namespace'] != 'my_service'", }, { Name: "Test fixed column", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "user.name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, Value: "john", Operator: "="}, {Key: v3.AttributeKey{Key: "k8s_namespace", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource}, Value: "my_service", Operator: "!="}, }}, ExpectedFilter: " AND user.name = 'john' AND resourceTagsMap['k8s_namespace'] != 'my_service'", }, { Name: "Test fixed column with empty value", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "user.name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, Value: "", Operator: "="}, {Key: v3.AttributeKey{Key: "k8s_namespace", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource}, Value: "my_service", Operator: "!="}, }}, ExpectedFilter: " AND user.name = '' AND resourceTagsMap['k8s_namespace'] != 'my_service'", }, { Name: "Test like", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "host", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "102.%", Operator: "like"}, }}, ExpectedFilter: " AND stringTagMap['host'] ILIKE '102.%'", }, { Name: "Test IN", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "bytes", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, Value: []interface{}{1, 2, 3, 4}, Operator: "in"}, }}, ExpectedFilter: " AND numberTagMap['bytes'] IN [1,2,3,4]", }, { Name: "Test DataType int64", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "bytes", DataType: v3.AttributeKeyDataTypeInt64, Type: v3.AttributeKeyTypeTag}, Value: 10, Operator: ">"}, }}, ExpectedFilter: " AND numberTagMap['bytes'] > 10", }, { Name: "Test NOT IN", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: []interface{}{"john", "bunny"}, Operator: "nin"}, }}, ExpectedFilter: " AND stringTagMap['name'] NOT IN ['john','bunny']", }, { Name: "Test exists", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "bytes", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "", Operator: "exists"}, }}, ExpectedFilter: " AND has(stringTagMap, 'bytes')", }, { Name: "Test exists with fixed column", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, Value: "", Operator: "exists"}, }}, ExpectedFilter: " AND name != ''", }, { Name: "Test not exists", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "bytes", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "", Operator: "nexists"}, }}, ExpectedFilter: " AND NOT has(stringTagMap, 'bytes')", }, { Name: "Test not exists with fixed column", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, Value: "", Operator: "nexists"}, }}, ExpectedFilter: " AND name = ''", }, { Name: "Test contains", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "host", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "102.", Operator: "contains"}, }}, ExpectedFilter: " AND stringTagMap['host'] ILIKE '%102.%'", }, { Name: "Test contains with quotes", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "message", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "Hello 'world'", Operator: "contains"}, }}, ExpectedFilter: " AND stringTagMap['message'] ILIKE '%Hello \\'world\\'%'", }, { Name: "Test not contains", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "host", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "102.", Operator: "ncontains"}, }}, ExpectedFilter: " AND stringTagMap['host'] NOT ILIKE '%102.%'", }, { Name: "Test regex", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, Value: "name: \"(?P\\S+)\"", Operator: "regex"}, }}, ExpectedFilter: " AND match(name, 'name: \"(?P\\\\S+)\"')", }, { Name: "Test not regex", FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "102.", Operator: "nregex"}, }}, ExpectedFilter: " AND NOT match(stringTagMap['name'], '102.')", }, } func TestBuildTracesFilterQuery(t *testing.T) { for _, tt := range buildFilterQueryData { Convey("TestBuildTracesFilterQuery", t, func() { query, err := buildTracesFilterQuery(tt.FilterSet, map[string]v3.AttributeKey{}) So(err, ShouldBeNil) So(query, ShouldEqual, tt.ExpectedFilter) }) } } var handleEmptyValuesInGroupByData = []struct { Name string GroupBy []v3.AttributeKey ExpectedFilter string }{ { Name: "String type key", GroupBy: []v3.AttributeKey{{Key: "bytes", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, ExpectedFilter: " AND has(stringTagMap, 'bytes')", }, { Name: "fixed column type key", GroupBy: []v3.AttributeKey{{Key: "bytes", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}}, ExpectedFilter: "", }, { Name: "String, float64 and fixed column type key", GroupBy: []v3.AttributeKey{ {Key: "bytes", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, {Key: "count", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, {Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, }, ExpectedFilter: " AND has(stringTagMap, 'bytes') AND has(numberTagMap, 'count')", }, } func TestBuildTracesHandleEmptyValuesInGroupBy(t *testing.T) { for _, tt := range handleEmptyValuesInGroupByData { Convey("TestBuildTracesHandleEmptyValuesInGroupBy", t, func() { query, err := handleEmptyValuesInGroupBy(map[string]v3.AttributeKey{}, tt.GroupBy) So(err, ShouldBeNil) So(query, ShouldEqual, tt.ExpectedFilter) }) } } var testColumnName = []struct { Name string AttributeKey v3.AttributeKey ExpectedColumn string }{ { Name: "resource", AttributeKey: v3.AttributeKey{Key: "collector_id", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource, IsColumn: false}, ExpectedColumn: "resourceTagsMap['collector_id']", }, { Name: "stringAttribute", AttributeKey: v3.AttributeKey{Key: "customer_id", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: false}, ExpectedColumn: "stringTagMap['customer_id']", }, { Name: "boolAttribute", AttributeKey: v3.AttributeKey{Key: "has_error", DataType: v3.AttributeKeyDataTypeBool, Type: v3.AttributeKeyTypeTag, IsColumn: false}, ExpectedColumn: "boolTagMap['has_error']", }, { Name: "float64Attribute", AttributeKey: v3.AttributeKey{Key: "count", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag, IsColumn: false}, ExpectedColumn: "numberTagMap['count']", }, { Name: "int64Attribute", AttributeKey: v3.AttributeKey{Key: "count", DataType: v3.AttributeKeyDataTypeInt64, Type: v3.AttributeKeyTypeTag, IsColumn: false}, ExpectedColumn: "numberTagMap['count']", }, { Name: "column", AttributeKey: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, ExpectedColumn: "name", }, { Name: "missing key", AttributeKey: v3.AttributeKey{Key: "xyz"}, ExpectedColumn: "stringTagMap['xyz']", }, } func TestColumnName(t *testing.T) { for _, tt := range testColumnName { Convey("testColumnName", t, func() { Column := getColumnName(tt.AttributeKey, map[string]v3.AttributeKey{}) So(Column, ShouldEqual, tt.ExpectedColumn) }) } } var testGetSelectLabelsData = []struct { Name string AggregateOperator v3.AggregateOperator GroupByTags []v3.AttributeKey SelectLabels string }{ { Name: "select keys for groupBy attribute", AggregateOperator: v3.AggregateOperatorCount, GroupByTags: []v3.AttributeKey{{Key: "user.name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, SelectLabels: " stringTagMap['user.name'] as `user.name`,", }, { Name: "select keys for groupBy resource", AggregateOperator: v3.AggregateOperatorCount, GroupByTags: []v3.AttributeKey{{Key: "user.name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource}}, SelectLabels: " resourceTagsMap['user.name'] as `user.name`,", }, { Name: "select keys for groupBy attribute and resource", AggregateOperator: v3.AggregateOperatorCount, GroupByTags: []v3.AttributeKey{ {Key: "user.name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource}, {Key: "host", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, }, SelectLabels: " resourceTagsMap['user.name'] as `user.name`, stringTagMap['host'] as `host`,", }, { Name: "select keys for groupBy fixed columns", AggregateOperator: v3.AggregateOperatorCount, GroupByTags: []v3.AttributeKey{{Key: "host", IsColumn: true, DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, SelectLabels: " host as `host`,", }, } func TestGetSelectLabels(t *testing.T) { for _, tt := range testGetSelectLabelsData { Convey("testGetSelectLabelsData", t, func() { selectLabels := getSelectLabels(tt.AggregateOperator, tt.GroupByTags, map[string]v3.AttributeKey{}) So(selectLabels, ShouldEqual, tt.SelectLabels) }) } } var testGetSelectColumnsData = []struct { Name string sc []v3.AttributeKey SelectColumns string }{ { Name: "select columns attribute", sc: []v3.AttributeKey{{Key: "user.name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, SelectColumns: "stringTagMap['user.name'] as `user.name` ", }, { Name: "select columns resource", sc: []v3.AttributeKey{{Key: "user.name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource}}, SelectColumns: "resourceTagsMap['user.name'] as `user.name` ", }, { Name: "select columns attribute and resource", sc: []v3.AttributeKey{ {Key: "user.name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource}, {Key: "host", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, }, SelectColumns: "resourceTagsMap['user.name'] as `user.name` ,stringTagMap['host'] as `host` ", }, { Name: "select columns fixed column", sc: []v3.AttributeKey{{Key: "host", IsColumn: true, DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, SelectColumns: "host as `host` ", }, } func TestGetSelectColumns(t *testing.T) { for _, tt := range testGetSelectColumnsData { Convey("testGetSelectColumnsData", t, func() { selectColumns := getSelectColumns(tt.sc, map[string]v3.AttributeKey{}) So(selectColumns, ShouldEqual, tt.SelectColumns) }) } } var testGetZerosForEpochNanoData = []struct { Name string Epoch int64 Multiplier int64 Result int64 }{ { Name: "Test 1", Epoch: 1680712080000, Multiplier: 1000000, Result: 1680712080000000000, }, { Name: "Test 2", Epoch: 1680712080000000000, Multiplier: 1, Result: 1680712080000000000, }, } func TestGetZerosForEpochNano(t *testing.T) { for _, tt := range testGetZerosForEpochNanoData { Convey("testGetZerosForEpochNanoData", t, func() { multiplier := getZerosForEpochNano(tt.Epoch) So(multiplier, ShouldEqual, tt.Multiplier) So(tt.Epoch*multiplier, ShouldEqual, tt.Result) }) } } var testOrderBy = []struct { Name string PanelType v3.PanelType Items []v3.OrderBy Tags []v3.AttributeKey Result string }{ { Name: "Test 1", PanelType: v3.PanelTypeGraph, Items: []v3.OrderBy{ { ColumnName: "name", Order: "asc", }, { ColumnName: constants.SigNozOrderByValue, Order: "desc", }, }, Tags: []v3.AttributeKey{ {Key: "name"}, }, Result: "`name` asc,value desc", }, { Name: "Test 2", PanelType: v3.PanelTypeList, Items: []v3.OrderBy{ { ColumnName: "name", Order: "asc", }, { ColumnName: "bytes", Order: "asc", }, }, Tags: []v3.AttributeKey{ {Key: "name"}, {Key: "bytes"}, }, Result: "`name` asc,`bytes` asc", }, { Name: "Test 3", PanelType: v3.PanelTypeList, Items: []v3.OrderBy{ { ColumnName: "name", Order: "asc", }, { ColumnName: constants.SigNozOrderByValue, Order: "asc", }, { ColumnName: "bytes", Order: "asc", }, }, Tags: []v3.AttributeKey{ {Key: "name"}, {Key: "bytes"}, }, Result: "`name` asc,value asc,`bytes` asc", }, { Name: "Test 4", PanelType: v3.PanelTypeList, Items: []v3.OrderBy{ { ColumnName: "name", Order: "asc", }, { ColumnName: "bytes", Order: "asc", }, { ColumnName: "response_time", Order: "desc", Key: "response_time", Type: v3.AttributeKeyTypeTag, DataType: v3.AttributeKeyDataTypeString, }, }, Tags: []v3.AttributeKey{ {Key: "name"}, {Key: "bytes"}, }, Result: "`name` asc,`bytes` asc,stringTagMap['response_time'] desc", }, { Name: "Test 5", PanelType: v3.PanelTypeList, Items: []v3.OrderBy{ { ColumnName: "name", Order: "asc", Key: "name", Type: v3.AttributeKeyTypeTag, DataType: v3.AttributeKeyDataTypeString, IsColumn: true, }, { ColumnName: "bytes", Order: "asc", Key: "bytes", Type: v3.AttributeKeyTypeTag, DataType: v3.AttributeKeyDataTypeString, IsColumn: true, }, { ColumnName: "response_time", Order: "desc", }, }, Tags: []v3.AttributeKey{}, Result: "`name` asc,`bytes` asc,stringTagMap['response_time'] desc", }, } func TestOrderBy(t *testing.T) { for _, tt := range testOrderBy { Convey("testOrderBy", t, func() { res := orderByAttributeKeyTags(tt.PanelType, tt.Items, tt.Tags, map[string]v3.AttributeKey{ "name": {Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, "bytes": {Key: "bytes", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, "response_time": {Key: "response_time", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: false}, }) So(res, ShouldResemble, tt.Result) }) } } var testBuildTracesQueryData = []struct { Name string Start int64 End int64 Step int64 BuilderQuery *v3.BuilderQuery GroupByTags []v3.AttributeKey TableName string AggregateOperator v3.AggregateOperator ExpectedQuery string PanelType v3.PanelType Options Options }{ { Name: "Test aggregate count on fixed column of float64 type", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateOperator: v3.AggregateOperatorCount, Expression: "A", AggregateAttribute: v3.AttributeKey{Key: "durationNano", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag, IsColumn: true}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count()) as value" + " from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')" + " group by ts order by value DESC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate rate without aggregate attribute", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateOperator: v3.AggregateOperatorRate, Expression: "A", }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, count()/1.000000 as value from" + " signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <=" + " '1680066458000000000') group by ts order by value DESC", PanelType: v3.PanelTypeGraph, Options: Options{GraphLimitQtype: "", PreferRPM: true}, }, { Name: "Test aggregate count on fixed column of float64 type with filter", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateOperator: v3.AggregateOperatorCount, Expression: "A", AggregateAttribute: v3.AttributeKey{Key: "durationNano", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag, IsColumn: true}, Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{{Key: v3.AttributeKey{Key: "customer_id", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "10001", Operator: "="}}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts," + " toFloat64(count()) as value from signoz_traces.distributed_signoz_index_v2" + " where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')" + " AND stringTagMap['customer_id'] = '10001' group by ts order by value DESC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate count on fixed column of bool type", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateOperator: v3.AggregateOperatorCount, Expression: "A", AggregateAttribute: v3.AttributeKey{Key: "hasError", DataType: v3.AttributeKeyDataTypeBool, Type: v3.AttributeKeyTypeTag, IsColumn: true}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count()) as value" + " from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')" + " group by ts order by value DESC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate count on a attribute", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "user_name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCount, Expression: "A", }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count()) as value" + " from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')" + " AND has(stringTagMap, 'user_name') group by ts order by value DESC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate count on a fixed column of string type", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, AggregateOperator: v3.AggregateOperatorCount, Expression: "A", }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count()) as value" + " from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')" + " AND name != '' group by ts order by value DESC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate count with filter", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "user_name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCount, Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "bytes", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, Value: 100, Operator: ">"}, }}, Expression: "A", }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count()) as value" + " from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')" + " AND numberTagMap['bytes'] > 100.000000 AND has(stringTagMap, 'user_name') group by ts order by value DESC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate count distinct and order by value", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "name", IsColumn: true, DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", OrderBy: []v3.OrderBy{{ColumnName: "#SIGNOZ_VALUE", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count(distinct(name))) as value" + " from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')" + " group by ts order by value ASC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate count distinct on string key", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count(distinct(stringTagMap['name'])))" + " as value from signoz_traces.distributed_signoz_index_v2 where" + " (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') group by ts order by value DESC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate count distinct with filter and groupBy", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "name", IsColumn: true, DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "http.method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, {Key: v3.AttributeKey{Key: "x", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource}, Value: "abc", Operator: "!="}, }, }, GroupBy: []v3.AttributeKey{{Key: "http.method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "http.method", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts," + " stringTagMap['http.method'] as `http.method`, " + "toFloat64(count(distinct(name))) as value from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND stringTagMap['http.method'] = 'GET' AND resourceTagsMap['x'] != 'abc' " + "AND has(stringTagMap, 'http.method') group by `http.method`,ts " + "order by `http.method` ASC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate count with multiple filter,groupBy and orderBy", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "name", IsColumn: true, DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, {Key: v3.AttributeKey{Key: "x", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource}, Value: "abc", Operator: "!="}, }, }, GroupBy: []v3.AttributeKey{ {Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, {Key: "x", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeResource}, }, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}, {ColumnName: "x", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts," + " stringTagMap['method'] as `method`, " + "resourceTagsMap['x'] as `x`, " + "toFloat64(count(distinct(name))) as value from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND stringTagMap['method'] = 'GET' AND resourceTagsMap['x'] != 'abc' " + "AND has(stringTagMap, 'method') AND has(resourceTagsMap, 'x') group by `method`,`x`,ts " + "order by `method` ASC,`x` ASC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate avg", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "bytes", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorAvg, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}, {ColumnName: "x", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts," + " stringTagMap['method'] as `method`, " + "avg(numberTagMap['bytes']) as value " + "from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND stringTagMap['method'] = 'GET' " + "AND has(stringTagMap, 'method') group by `method`,ts " + "order by `method` ASC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate sum", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "bytes", IsColumn: true, DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorSum, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts," + " stringTagMap['method'] as `method`, " + "sum(bytes) as value " + "from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND stringTagMap['method'] = 'GET' " + "AND has(stringTagMap, 'method') group by `method`,ts " + "order by `method` ASC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate min", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "bytes", IsColumn: true, DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorMin, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts," + " stringTagMap['method'] as `method`, " + "min(bytes) as value " + "from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND stringTagMap['method'] = 'GET' " + "AND has(stringTagMap, 'method') group by `method`,ts " + "order by `method` ASC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate max", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "bytes", IsColumn: true, DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorMax, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts," + " stringTagMap['method'] as `method`, " + "max(bytes) as value " + "from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND stringTagMap['method'] = 'GET' " + "AND has(stringTagMap, 'method') group by `method`,ts " + "order by `method` ASC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate PXX", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "bytes", IsColumn: true, DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorP05, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{}}, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts," + " stringTagMap['method'] as `method`, " + "quantile(0.05)(bytes) as value " + "from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND has(stringTagMap, 'method') group by `method`,ts " + "order by `method` ASC", PanelType: v3.PanelTypeGraph, }, { Name: "Test aggregate RateSum", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "bytes", IsColumn: true, DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorRateSum, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{}}, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, stringTagMap['method'] as `method`" + ", sum(bytes)/60.000000 as value from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')" + " AND has(stringTagMap, 'method') group by `method`,ts order by `method` ASC", PanelType: v3.PanelTypeGraph, Options: Options{GraphLimitQtype: "", PreferRPM: false, }, }, { Name: "Test aggregate rate", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "bytes", Type: v3.AttributeKeyTypeTag, DataType: v3.AttributeKeyDataTypeFloat64}, AggregateOperator: v3.AggregateOperatorRate, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{}}, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, stringTagMap['method'] as `method`" + ", count(numberTagMap['bytes'])/1.000000 as value " + "from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND has(stringTagMap, 'method') group by `method`,ts " + "order by `method` ASC", PanelType: v3.PanelTypeGraph, Options: Options{GraphLimitQtype: "", PreferRPM: true}, }, { Name: "Test aggregate RateSum without fixed column", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "bytes", Type: v3.AttributeKeyTypeTag, DataType: v3.AttributeKeyDataTypeFloat64}, AggregateOperator: v3.AggregateOperatorRateSum, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{}}, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, " + "stringTagMap['method'] as `method`, " + "sum(numberTagMap['bytes'])/1.000000 as value " + "from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND has(stringTagMap, 'method') group by `method`,ts " + "order by `method` ASC", PanelType: v3.PanelTypeGraph, Options: Options{GraphLimitQtype: "", PreferRPM: true}, }, { Name: "Test aggregate with having clause", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Having: []v3.Having{ { ColumnName: "name", Operator: ">", Value: 10, }, }, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count(distinct(stringTagMap['name']))) as value" + " from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')" + " group by ts having value > 10 order by value DESC", PanelType: v3.PanelTypeGraph, }, { Name: "Test count aggregate with having clause and filters", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCount, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, Having: []v3.Having{ { ColumnName: "name", Operator: ">", Value: 10, }, }, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count()) as value from " + "signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND stringTagMap['method'] = 'GET' AND has(stringTagMap, 'name') group by ts having value > 10 order by value DESC", PanelType: v3.PanelTypeGraph, }, { Name: "Test count distinct aggregate with having clause and filters", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, Having: []v3.Having{ { ColumnName: "name", Operator: ">", Value: 10, }, }, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count(distinct(stringTagMap['name']))) as value" + " from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND stringTagMap['method'] = 'GET' group by ts having value > 10 order by value DESC", PanelType: v3.PanelTypeGraph, }, { Name: "Test count with having clause and filters", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCount, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, Having: []v3.Having{ { ColumnName: "name", Operator: ">", Value: 10, }, }, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, toFloat64(count()) as value" + " from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND stringTagMap['method'] = 'GET' AND has(stringTagMap, 'name') group by ts having value > 10", PanelType: v3.PanelTypeValue, }, { Name: "Test aggregate PXX with groupby", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "durationNano", IsColumn: true, DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorP05, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{}}, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT now() as ts, stringTagMap['method'] as `method`, " + "quantile(0.05)(durationNano) as value " + "from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " + "AND has(stringTagMap, 'method') group by `method` " + "order by `method` ASC", PanelType: v3.PanelTypeTable, }, { Name: "Test aggregate PXX", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "durationNano", IsColumn: true, DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorP05, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{}}, GroupBy: []v3.AttributeKey{}, OrderBy: []v3.OrderBy{}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT now() as ts, quantile(0.05)(durationNano) as value " + "from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')", PanelType: v3.PanelTypeTable, }, { Name: "Test aggregate rate table panel", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, AggregateAttribute: v3.AttributeKey{Key: "durationNano", IsColumn: true, DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorRate, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{}}, GroupBy: []v3.AttributeKey{}, OrderBy: []v3.OrderBy{}, }, TableName: "signoz_traces.distributed_signoz_index_v2", ExpectedQuery: "SELECT now() as ts, count(durationNano)/97.000000 as value " + "from signoz_traces.distributed_signoz_index_v2 " + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')", PanelType: v3.PanelTypeTable, }, { Name: "Test Noop list view", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ SelectColumns: []v3.AttributeKey{ {Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, }, QueryName: "A", AggregateOperator: v3.AggregateOperatorNoOp, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{}}, }, ExpectedQuery: "SELECT timestamp as timestamp_datetime, spanID, traceID," + " name as `name` from signoz_traces.distributed_signoz_index_v2 where " + "(timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') order by timestamp DESC", PanelType: v3.PanelTypeList, }, { Name: "Test Noop list view with order by", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ SelectColumns: []v3.AttributeKey{ {Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, }, QueryName: "A", AggregateOperator: v3.AggregateOperatorNoOp, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{}}, OrderBy: []v3.OrderBy{{ColumnName: "name", Order: "ASC"}}, }, ExpectedQuery: "SELECT timestamp as timestamp_datetime, spanID, traceID," + " name as `name` from signoz_traces.distributed_signoz_index_v2 where " + "(timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') order by `name` ASC", PanelType: v3.PanelTypeList, }, { Name: "Test Noop list view with order by and filter", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ SelectColumns: []v3.AttributeKey{ {Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, }, QueryName: "A", AggregateOperator: v3.AggregateOperatorNoOp, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }}, OrderBy: []v3.OrderBy{{ColumnName: "name", Order: "ASC"}}, }, ExpectedQuery: "SELECT timestamp as timestamp_datetime, spanID, traceID," + " name as `name` from signoz_traces.distributed_signoz_index_v2 where " + "(timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')" + " AND stringTagMap['method'] = 'GET' order by `name` ASC", PanelType: v3.PanelTypeList, }, { Name: "Test Noop trace view", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", AggregateOperator: v3.AggregateOperatorNoOp, Expression: "A", Filters: &v3.FilterSet{ Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, }, ExpectedQuery: "WITH subQuery AS (SELECT distinct on (traceID) traceID, durationNano, serviceName," + " name FROM signoz_traces.distributed_signoz_index_v2 WHERE parentSpanID = '' AND (timestamp >= '1680066360726210000' AND " + "timestamp <= '1680066458000000000') AND stringTagMap['method'] = 'GET' ORDER BY durationNano DESC LIMIT 100)" + " SELECT subQuery.serviceName, subQuery.name, count() AS span_count, subQuery.durationNano, traceID" + " FROM signoz_traces.distributed_signoz_index_v2 GLOBAL INNER JOIN subQuery ON distributed_signoz_index_v2.traceID" + " = subQuery.traceID GROUP BY traceID, subQuery.durationNano, subQuery.name, subQuery.serviceName " + "ORDER BY subQuery.durationNano desc;", PanelType: v3.PanelTypeTrace, }, } func TestBuildTracesQuery(t *testing.T) { for _, tt := range testBuildTracesQueryData { Convey("TestBuildTracesQuery", t, func() { query, err := buildTracesQuery(tt.Start, tt.End, tt.BuilderQuery.StepInterval, tt.BuilderQuery, tt.TableName, map[string]v3.AttributeKey{ "name": {Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, }, tt.PanelType, tt.Options) So(err, ShouldBeNil) So(query, ShouldEqual, tt.ExpectedQuery) }) } } var testPrepTracesQueryData = []struct { Name string PanelType v3.PanelType Start int64 End int64 BuilderQuery *v3.BuilderQuery ExpectedQuery string Keys map[string]v3.AttributeKey Options Options }{ { Name: "Test TS with limit- first", PanelType: v3.PanelTypeGraph, Start: 1680066360726, End: 1680066458000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, Limit: 10, StepInterval: 60, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, }, ExpectedQuery: "SELECT `method` from (SELECT stringTagMap['method'] as `method`," + " toFloat64(count(distinct(stringTagMap['name']))) as value from signoz_traces.distributed_signoz_index_v2" + " where (timestamp >= '1680066360000000000' AND timestamp <= '1680066420000000000') AND" + " stringTagMap['method'] = 'GET' AND has(stringTagMap, 'method') group by `method` order by value DESC) LIMIT 10", Keys: map[string]v3.AttributeKey{"name": {Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}}, Options: Options{ GraphLimitQtype: constants.FirstQueryGraphLimit, }, }, { Name: "Test TS with limit- first - with order by value", PanelType: v3.PanelTypeGraph, Start: 1680066360726, End: 1680066458000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, Limit: 10, StepInterval: 60, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: constants.SigNozOrderByValue, Order: "ASC"}}, }, ExpectedQuery: "SELECT `method` from (SELECT stringTagMap['method'] as `method`," + " toFloat64(count(distinct(stringTagMap['name']))) as value from " + "signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360000000000'" + " AND timestamp <= '1680066420000000000') AND stringTagMap['method'] = 'GET' AND" + " has(stringTagMap, 'method') group by `method` order by value ASC) LIMIT 10", Keys: map[string]v3.AttributeKey{}, Options: Options{ GraphLimitQtype: constants.FirstQueryGraphLimit, }, }, { Name: "Test TS with limit- first - with order by attribute", PanelType: v3.PanelTypeGraph, Start: 1680066360726, End: 1680066458000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", AggregateAttribute: v3.AttributeKey{Key: "serviceName", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Filters: &v3.FilterSet{}, Limit: 10, StepInterval: 60, GroupBy: []v3.AttributeKey{{Key: "serviceName", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}}, OrderBy: []v3.OrderBy{{ColumnName: "serviceName", Order: "ASC"}}, }, ExpectedQuery: "SELECT `serviceName` from (SELECT serviceName as `serviceName`," + " toFloat64(count(distinct(serviceName))) as value from " + "signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360000000000'" + " AND timestamp <= '1680066420000000000') " + "group by `serviceName` order by `serviceName` ASC) LIMIT 10", Keys: map[string]v3.AttributeKey{}, Options: Options{ GraphLimitQtype: constants.FirstQueryGraphLimit, }, }, { Name: "Test TS with limit- first - with 2 group by and 2 order by", PanelType: v3.PanelTypeGraph, Start: 1680066360726, End: 1680066458000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", AggregateAttribute: v3.AttributeKey{Key: "serviceName", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Filters: &v3.FilterSet{}, Limit: 10, StepInterval: 60, GroupBy: []v3.AttributeKey{ {Key: "serviceName", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}, {Key: "http.method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, }, OrderBy: []v3.OrderBy{{ColumnName: "serviceName", Order: "ASC"}, {ColumnName: constants.SigNozOrderByValue, Order: "ASC"}}, }, ExpectedQuery: "SELECT `serviceName`,`http.method` from (SELECT serviceName as `serviceName`," + " stringTagMap['http.method'] as `http.method`," + " toFloat64(count(distinct(serviceName))) as value from " + "signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360000000000'" + " AND timestamp <= '1680066420000000000') AND has(stringTagMap, 'http.method') " + "group by `serviceName`,`http.method` order by `serviceName` ASC,value ASC) LIMIT 10", Keys: map[string]v3.AttributeKey{}, Options: Options{ GraphLimitQtype: constants.FirstQueryGraphLimit, }, }, { Name: "Test TS with limit- second", PanelType: v3.PanelTypeGraph, Start: 1680066360726, End: 1680066458000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, Limit: 2, StepInterval: 60, }, ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, " + "stringTagMap['method'] as `method`, toFloat64(count(distinct(stringTagMap['name'])))" + " as value from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360000000000'" + " AND timestamp <= '1680066420000000000') AND stringTagMap['method'] = 'GET' AND" + " has(stringTagMap, 'method') AND (`method`) GLOBAL IN (%s) group by `method`,ts order by value DESC", Keys: map[string]v3.AttributeKey{}, Options: Options{ GraphLimitQtype: constants.SecondQueryGraphLimit, }, }, { Name: "Test TS with limit- second - with order by", PanelType: v3.PanelTypeGraph, Start: 1680066360726, End: 1680066458000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, GroupBy: []v3.AttributeKey{{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}}, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}}, Limit: 2, StepInterval: 60, }, ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, " + "stringTagMap['method'] as `method`, toFloat64(count(distinct(stringTagMap['name'])))" + " as value from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360000000000'" + " AND timestamp <= '1680066420000000000') AND stringTagMap['method'] = 'GET' AND" + " has(stringTagMap, 'method') AND (`method`) GLOBAL IN (%s) group by `method`,ts order by `method` ASC", Keys: map[string]v3.AttributeKey{}, Options: Options{ GraphLimitQtype: constants.SecondQueryGraphLimit, }, }, { Name: "Test TS with limit - second - with two group by and two order by", PanelType: v3.PanelTypeGraph, Start: 1680066360726, End: 1680066458000, BuilderQuery: &v3.BuilderQuery{ QueryName: "A", AggregateAttribute: v3.AttributeKey{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, AggregateOperator: v3.AggregateOperatorCountDistinct, Expression: "A", Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{ {Key: v3.AttributeKey{Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "GET", Operator: "="}, }, }, GroupBy: []v3.AttributeKey{ {Key: "method", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, {Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, }, OrderBy: []v3.OrderBy{{ColumnName: "method", Order: "ASC"}, {ColumnName: "name", Order: "ASC"}}, Limit: 2, StepInterval: 60, }, ExpectedQuery: "SELECT toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, " + "stringTagMap['method'] as `method`, stringTagMap['name'] as `name`," + " toFloat64(count(distinct(stringTagMap['name'])))" + " as value from signoz_traces.distributed_signoz_index_v2 where (timestamp >= '1680066360000000000'" + " AND timestamp <= '1680066420000000000') AND stringTagMap['method'] = 'GET' AND" + " has(stringTagMap, 'method') AND has(stringTagMap, 'name') " + "AND (`method`,`name`) GLOBAL IN (%s) group by `method`,`name`,ts " + "order by `method` ASC,`name` ASC", Keys: map[string]v3.AttributeKey{}, Options: Options{ GraphLimitQtype: constants.SecondQueryGraphLimit, }, }, } func TestPrepareTracesQuery(t *testing.T) { for _, tt := range testPrepTracesQueryData { Convey("TestPrepareTracesQuery", t, func() { query, err := PrepareTracesQuery(tt.Start, tt.End, tt.PanelType, tt.BuilderQuery, tt.Keys, tt.Options) So(err, ShouldBeNil) So(query, ShouldEqual, tt.ExpectedQuery) }) } }