chore: use *_keys tables instead of tag_attributes_v2 for suggestions (#8753)

This commit is contained in:
Srikanth Chekuri 2025-08-12 18:10:35 +05:30 committed by GitHub
parent 3a952fa330
commit 5fa70ea802
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 287 additions and 127 deletions

View File

@ -31,6 +31,7 @@ func NewAPI(
telemetryStore, telemetryStore,
telemetrytraces.DBName, telemetrytraces.DBName,
telemetrytraces.TagAttributesV2TableName, telemetrytraces.TagAttributesV2TableName,
telemetrytraces.SpanAttributesKeysTblName,
telemetrytraces.SpanIndexV3TableName, telemetrytraces.SpanIndexV3TableName,
telemetrymetrics.DBName, telemetrymetrics.DBName,
telemetrymetrics.AttributesMetadataTableName, telemetrymetrics.AttributesMetadataTableName,
@ -39,6 +40,8 @@ func NewAPI(
telemetrylogs.DBName, telemetrylogs.DBName,
telemetrylogs.LogsV2TableName, telemetrylogs.LogsV2TableName,
telemetrylogs.TagAttributesV2TableName, telemetrylogs.TagAttributesV2TableName,
telemetrylogs.LogAttributeKeysTblName,
telemetrylogs.LogResourceKeysTblName,
telemetrymetadata.DBName, telemetrymetadata.DBName,
telemetrymetadata.AttributesMetadataLocalTableName, telemetrymetadata.AttributesMetadataLocalTableName,
) )

View File

@ -50,6 +50,7 @@ func newProvider(
telemetryStore, telemetryStore,
telemetrytraces.DBName, telemetrytraces.DBName,
telemetrytraces.TagAttributesV2TableName, telemetrytraces.TagAttributesV2TableName,
telemetrytraces.SpanAttributesKeysTblName,
telemetrytraces.SpanIndexV3TableName, telemetrytraces.SpanIndexV3TableName,
telemetrymetrics.DBName, telemetrymetrics.DBName,
telemetrymetrics.AttributesMetadataTableName, telemetrymetrics.AttributesMetadataTableName,
@ -58,6 +59,8 @@ func newProvider(
telemetrylogs.DBName, telemetrylogs.DBName,
telemetrylogs.LogsV2TableName, telemetrylogs.LogsV2TableName,
telemetrylogs.TagAttributesV2TableName, telemetrylogs.TagAttributesV2TableName,
telemetrylogs.LogAttributeKeysTblName,
telemetrylogs.LogResourceKeysTblName,
telemetrymetadata.DBName, telemetrymetadata.DBName,
telemetrymetadata.AttributesMetadataLocalTableName, telemetrymetadata.AttributesMetadataLocalTableName,
) )
@ -69,12 +72,13 @@ func newProvider(
resourceFilterFieldMapper := resourcefilter.NewFieldMapper() resourceFilterFieldMapper := resourcefilter.NewFieldMapper()
resourceFilterConditionBuilder := resourcefilter.NewConditionBuilder(resourceFilterFieldMapper) resourceFilterConditionBuilder := resourcefilter.NewConditionBuilder(resourceFilterFieldMapper)
resourceFilterStmtBuilder := resourcefilter.NewTraceResourceFilterStatementBuilder( resourceFilterStmtBuilder := resourcefilter.NewTraceResourceFilterStatementBuilder(
settings,
resourceFilterFieldMapper, resourceFilterFieldMapper,
resourceFilterConditionBuilder, resourceFilterConditionBuilder,
telemetryMetadataStore, telemetryMetadataStore,
) )
traceAggExprRewriter := querybuilder.NewAggExprRewriter(nil, traceFieldMapper, traceConditionBuilder, "", nil) traceAggExprRewriter := querybuilder.NewAggExprRewriter(settings, nil, traceFieldMapper, traceConditionBuilder, "", nil)
traceStmtBuilder := telemetrytraces.NewTraceQueryStatementBuilder( traceStmtBuilder := telemetrytraces.NewTraceQueryStatementBuilder(
settings, settings,
telemetryMetadataStore, telemetryMetadataStore,
@ -89,6 +93,7 @@ func newProvider(
logFieldMapper := telemetrylogs.NewFieldMapper() logFieldMapper := telemetrylogs.NewFieldMapper()
logConditionBuilder := telemetrylogs.NewConditionBuilder(logFieldMapper) logConditionBuilder := telemetrylogs.NewConditionBuilder(logFieldMapper)
logResourceFilterStmtBuilder := resourcefilter.NewLogResourceFilterStatementBuilder( logResourceFilterStmtBuilder := resourcefilter.NewLogResourceFilterStatementBuilder(
settings,
resourceFilterFieldMapper, resourceFilterFieldMapper,
resourceFilterConditionBuilder, resourceFilterConditionBuilder,
telemetryMetadataStore, telemetryMetadataStore,
@ -97,6 +102,7 @@ func newProvider(
telemetrylogs.GetBodyJSONKey, telemetrylogs.GetBodyJSONKey,
) )
logAggExprRewriter := querybuilder.NewAggExprRewriter( logAggExprRewriter := querybuilder.NewAggExprRewriter(
settings,
telemetrylogs.DefaultFullTextColumn, telemetrylogs.DefaultFullTextColumn,
logFieldMapper, logFieldMapper,
logConditionBuilder, logConditionBuilder,

View File

@ -3,10 +3,12 @@ package querybuilder
import ( import (
"context" "context"
"fmt" "fmt"
"log/slog"
"strings" "strings"
chparser "github.com/AfterShip/clickhouse-sql-parser/parser" chparser "github.com/AfterShip/clickhouse-sql-parser/parser"
"github.com/SigNoz/signoz/pkg/errors" "github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5" qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
"github.com/SigNoz/signoz/pkg/types/telemetrytypes" "github.com/SigNoz/signoz/pkg/types/telemetrytypes"
"github.com/SigNoz/signoz/pkg/valuer" "github.com/SigNoz/signoz/pkg/valuer"
@ -14,6 +16,7 @@ import (
) )
type aggExprRewriter struct { type aggExprRewriter struct {
logger *slog.Logger
fullTextColumn *telemetrytypes.TelemetryFieldKey fullTextColumn *telemetrytypes.TelemetryFieldKey
fieldMapper qbtypes.FieldMapper fieldMapper qbtypes.FieldMapper
conditionBuilder qbtypes.ConditionBuilder conditionBuilder qbtypes.ConditionBuilder
@ -24,13 +27,17 @@ type aggExprRewriter struct {
var _ qbtypes.AggExprRewriter = (*aggExprRewriter)(nil) var _ qbtypes.AggExprRewriter = (*aggExprRewriter)(nil)
func NewAggExprRewriter( func NewAggExprRewriter(
settings factory.ProviderSettings,
fullTextColumn *telemetrytypes.TelemetryFieldKey, fullTextColumn *telemetrytypes.TelemetryFieldKey,
fieldMapper qbtypes.FieldMapper, fieldMapper qbtypes.FieldMapper,
conditionBuilder qbtypes.ConditionBuilder, conditionBuilder qbtypes.ConditionBuilder,
jsonBodyPrefix string, jsonBodyPrefix string,
jsonKeyToKey qbtypes.JsonKeyToFieldFunc, jsonKeyToKey qbtypes.JsonKeyToFieldFunc,
) *aggExprRewriter { ) *aggExprRewriter {
set := factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/pkg/querybuilder/agg_rewrite")
return &aggExprRewriter{ return &aggExprRewriter{
logger: set.Logger(),
fullTextColumn: fullTextColumn, fullTextColumn: fullTextColumn,
fieldMapper: fieldMapper, fieldMapper: fieldMapper,
conditionBuilder: conditionBuilder, conditionBuilder: conditionBuilder,
@ -70,7 +77,7 @@ func (r *aggExprRewriter) Rewrite(
return "", nil, errors.NewInternalf(errors.CodeInternal, "no SELECT items for %q", expr) return "", nil, errors.NewInternalf(errors.CodeInternal, "no SELECT items for %q", expr)
} }
visitor := newExprVisitor(keys, visitor := newExprVisitor(r.logger, keys,
r.fullTextColumn, r.fullTextColumn,
r.fieldMapper, r.fieldMapper,
r.conditionBuilder, r.conditionBuilder,
@ -117,6 +124,7 @@ func (r *aggExprRewriter) RewriteMulti(
// exprVisitor walks FunctionExpr nodes and applies the mappers. // exprVisitor walks FunctionExpr nodes and applies the mappers.
type exprVisitor struct { type exprVisitor struct {
chparser.DefaultASTVisitor chparser.DefaultASTVisitor
logger *slog.Logger
fieldKeys map[string][]*telemetrytypes.TelemetryFieldKey fieldKeys map[string][]*telemetrytypes.TelemetryFieldKey
fullTextColumn *telemetrytypes.TelemetryFieldKey fullTextColumn *telemetrytypes.TelemetryFieldKey
fieldMapper qbtypes.FieldMapper fieldMapper qbtypes.FieldMapper
@ -129,6 +137,7 @@ type exprVisitor struct {
} }
func newExprVisitor( func newExprVisitor(
logger *slog.Logger,
fieldKeys map[string][]*telemetrytypes.TelemetryFieldKey, fieldKeys map[string][]*telemetrytypes.TelemetryFieldKey,
fullTextColumn *telemetrytypes.TelemetryFieldKey, fullTextColumn *telemetrytypes.TelemetryFieldKey,
fieldMapper qbtypes.FieldMapper, fieldMapper qbtypes.FieldMapper,
@ -137,6 +146,7 @@ func newExprVisitor(
jsonKeyToKey qbtypes.JsonKeyToFieldFunc, jsonKeyToKey qbtypes.JsonKeyToFieldFunc,
) *exprVisitor { ) *exprVisitor {
return &exprVisitor{ return &exprVisitor{
logger: logger,
fieldKeys: fieldKeys, fieldKeys: fieldKeys,
fullTextColumn: fullTextColumn, fullTextColumn: fullTextColumn,
fieldMapper: fieldMapper, fieldMapper: fieldMapper,
@ -183,6 +193,7 @@ func (v *exprVisitor) VisitFunctionExpr(fn *chparser.FunctionExpr) error {
whereClause, err := PrepareWhereClause( whereClause, err := PrepareWhereClause(
origPred, origPred,
FilterExprVisitorOpts{ FilterExprVisitorOpts{
Logger: v.logger,
FieldKeys: v.fieldKeys, FieldKeys: v.fieldKeys,
FieldMapper: v.fieldMapper, FieldMapper: v.fieldMapper,
ConditionBuilder: v.conditionBuilder, ConditionBuilder: v.conditionBuilder,

View File

@ -3,8 +3,10 @@ package resourcefilter
import ( import (
"context" "context"
"fmt" "fmt"
"log/slog"
"github.com/SigNoz/signoz/pkg/errors" "github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/querybuilder" "github.com/SigNoz/signoz/pkg/querybuilder"
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5" qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
"github.com/SigNoz/signoz/pkg/types/telemetrytypes" "github.com/SigNoz/signoz/pkg/types/telemetrytypes"
@ -34,6 +36,7 @@ var signalConfigs = map[telemetrytypes.Signal]signalConfig{
// Generic resource filter statement builder // Generic resource filter statement builder
type resourceFilterStatementBuilder[T any] struct { type resourceFilterStatementBuilder[T any] struct {
logger *slog.Logger
fieldMapper qbtypes.FieldMapper fieldMapper qbtypes.FieldMapper
conditionBuilder qbtypes.ConditionBuilder conditionBuilder qbtypes.ConditionBuilder
metadataStore telemetrytypes.MetadataStore metadataStore telemetrytypes.MetadataStore
@ -52,11 +55,14 @@ var (
// Constructor functions // Constructor functions
func NewTraceResourceFilterStatementBuilder( func NewTraceResourceFilterStatementBuilder(
settings factory.ProviderSettings,
fieldMapper qbtypes.FieldMapper, fieldMapper qbtypes.FieldMapper,
conditionBuilder qbtypes.ConditionBuilder, conditionBuilder qbtypes.ConditionBuilder,
metadataStore telemetrytypes.MetadataStore, metadataStore telemetrytypes.MetadataStore,
) *resourceFilterStatementBuilder[qbtypes.TraceAggregation] { ) *resourceFilterStatementBuilder[qbtypes.TraceAggregation] {
set := factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/pkg/querybuilder/resourcefilter")
return &resourceFilterStatementBuilder[qbtypes.TraceAggregation]{ return &resourceFilterStatementBuilder[qbtypes.TraceAggregation]{
logger: set.Logger(),
fieldMapper: fieldMapper, fieldMapper: fieldMapper,
conditionBuilder: conditionBuilder, conditionBuilder: conditionBuilder,
metadataStore: metadataStore, metadataStore: metadataStore,
@ -65,6 +71,7 @@ func NewTraceResourceFilterStatementBuilder(
} }
func NewLogResourceFilterStatementBuilder( func NewLogResourceFilterStatementBuilder(
settings factory.ProviderSettings,
fieldMapper qbtypes.FieldMapper, fieldMapper qbtypes.FieldMapper,
conditionBuilder qbtypes.ConditionBuilder, conditionBuilder qbtypes.ConditionBuilder,
metadataStore telemetrytypes.MetadataStore, metadataStore telemetrytypes.MetadataStore,
@ -72,7 +79,9 @@ func NewLogResourceFilterStatementBuilder(
jsonBodyPrefix string, jsonBodyPrefix string,
jsonKeyToKey qbtypes.JsonKeyToFieldFunc, jsonKeyToKey qbtypes.JsonKeyToFieldFunc,
) *resourceFilterStatementBuilder[qbtypes.LogAggregation] { ) *resourceFilterStatementBuilder[qbtypes.LogAggregation] {
set := factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/pkg/querybuilder/resourcefilter")
return &resourceFilterStatementBuilder[qbtypes.LogAggregation]{ return &resourceFilterStatementBuilder[qbtypes.LogAggregation]{
logger: set.Logger(),
fieldMapper: fieldMapper, fieldMapper: fieldMapper,
conditionBuilder: conditionBuilder, conditionBuilder: conditionBuilder,
metadataStore: metadataStore, metadataStore: metadataStore,
@ -148,6 +157,7 @@ func (b *resourceFilterStatementBuilder[T]) addConditions(
// warnings would be encountered as part of the main condition already // warnings would be encountered as part of the main condition already
filterWhereClause, err := querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{ filterWhereClause, err := querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{
Logger: b.logger,
FieldMapper: b.fieldMapper, FieldMapper: b.fieldMapper,
ConditionBuilder: b.conditionBuilder, ConditionBuilder: b.conditionBuilder,
FieldKeys: keys, FieldKeys: keys,

View File

@ -3,6 +3,7 @@ package querybuilder
import ( import (
"context" "context"
"fmt" "fmt"
"log/slog"
"strconv" "strconv"
"strings" "strings"
@ -20,6 +21,7 @@ var searchTroubleshootingGuideURL = "https://signoz.io/docs/userguide/search-tro
// filterExpressionVisitor implements the FilterQueryVisitor interface // filterExpressionVisitor implements the FilterQueryVisitor interface
// to convert the parsed filter expressions into ClickHouse WHERE clause // to convert the parsed filter expressions into ClickHouse WHERE clause
type filterExpressionVisitor struct { type filterExpressionVisitor struct {
logger *slog.Logger
fieldMapper qbtypes.FieldMapper fieldMapper qbtypes.FieldMapper
conditionBuilder qbtypes.ConditionBuilder conditionBuilder qbtypes.ConditionBuilder
warnings []string warnings []string
@ -41,6 +43,7 @@ type filterExpressionVisitor struct {
} }
type FilterExprVisitorOpts struct { type FilterExprVisitorOpts struct {
Logger *slog.Logger
FieldMapper qbtypes.FieldMapper FieldMapper qbtypes.FieldMapper
ConditionBuilder qbtypes.ConditionBuilder ConditionBuilder qbtypes.ConditionBuilder
FieldKeys map[string][]*telemetrytypes.TelemetryFieldKey FieldKeys map[string][]*telemetrytypes.TelemetryFieldKey
@ -58,6 +61,7 @@ type FilterExprVisitorOpts struct {
// newFilterExpressionVisitor creates a new filterExpressionVisitor // newFilterExpressionVisitor creates a new filterExpressionVisitor
func newFilterExpressionVisitor(opts FilterExprVisitorOpts) *filterExpressionVisitor { func newFilterExpressionVisitor(opts FilterExprVisitorOpts) *filterExpressionVisitor {
return &filterExpressionVisitor{ return &filterExpressionVisitor{
logger: opts.Logger,
fieldMapper: opts.FieldMapper, fieldMapper: opts.FieldMapper,
conditionBuilder: opts.ConditionBuilder, conditionBuilder: opts.ConditionBuilder,
fieldKeys: opts.FieldKeys, fieldKeys: opts.FieldKeys,
@ -786,15 +790,35 @@ func (v *filterExpressionVisitor) VisitKey(ctx *grammar.KeyContext) any {
} }
if len(fieldKeysForName) > 1 && !v.keysWithWarnings[keyName] { if len(fieldKeysForName) > 1 && !v.keysWithWarnings[keyName] {
v.mainWarnURL = "https://signoz.io/docs/userguide/field-context-data-types/" warnMsg := fmt.Sprintf(
// this is warning state, we must have a unambiguous key "Key `%s` is ambiguous, found %d different combinations of field context / data type: %v.",
v.warnings = append(v.warnings, fmt.Sprintf(
"key `%s` is ambiguous, found %d different combinations of field context / data type: %v",
fieldKey.Name, fieldKey.Name,
len(fieldKeysForName), len(fieldKeysForName),
fieldKeysForName, fieldKeysForName,
)) )
mixedFieldContext := map[string]bool{}
for _, item := range fieldKeysForName {
mixedFieldContext[item.FieldContext.StringValue()] = true
}
if mixedFieldContext[telemetrytypes.FieldContextResource.StringValue()] &&
mixedFieldContext[telemetrytypes.FieldContextAttribute.StringValue()] {
filteredKeys := []*telemetrytypes.TelemetryFieldKey{}
for _, item := range fieldKeysForName {
if item.FieldContext != telemetrytypes.FieldContextResource {
continue
}
filteredKeys = append(filteredKeys, item)
}
fieldKeysForName = filteredKeys
warnMsg += " " + "Using `resource` context by default. To query attributes explicitly, " +
fmt.Sprintf("use the fully qualified name (e.g., 'attribute.%s')", fieldKey.Name)
}
v.mainWarnURL = "https://signoz.io/docs/userguide/field-context-data-types/"
// this is warning state, we must have a unambiguous key
v.warnings = append(v.warnings, warnMsg)
v.keysWithWarnings[keyName] = true v.keysWithWarnings[keyName] = true
v.logger.Warn("ambiguous key", "field_key_name", fieldKey.Name) //nolint:sloglint
} }
return fieldKeysForName return fieldKeysForName

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest"
"github.com/SigNoz/signoz/pkg/querybuilder" "github.com/SigNoz/signoz/pkg/querybuilder"
"github.com/SigNoz/signoz/pkg/types/telemetrytypes" "github.com/SigNoz/signoz/pkg/types/telemetrytypes"
"github.com/huandu/go-sqlbuilder" "github.com/huandu/go-sqlbuilder"
@ -19,6 +20,7 @@ func TestFilterExprLogsBodyJSON(t *testing.T) {
keys := buildCompleteFieldKeyMap() keys := buildCompleteFieldKeyMap()
opts := querybuilder.FilterExprVisitorOpts{ opts := querybuilder.FilterExprVisitorOpts{
Logger: instrumentationtest.New().Logger(),
FieldMapper: fm, FieldMapper: fm,
ConditionBuilder: cb, ConditionBuilder: cb,
FieldKeys: keys, FieldKeys: keys,

View File

@ -6,6 +6,7 @@ import (
"testing" "testing"
"github.com/SigNoz/signoz/pkg/errors" "github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest"
"github.com/SigNoz/signoz/pkg/querybuilder" "github.com/SigNoz/signoz/pkg/querybuilder"
"github.com/SigNoz/signoz/pkg/types/telemetrytypes" "github.com/SigNoz/signoz/pkg/types/telemetrytypes"
"github.com/huandu/go-sqlbuilder" "github.com/huandu/go-sqlbuilder"
@ -21,6 +22,7 @@ func TestFilterExprLogs(t *testing.T) {
keys := buildCompleteFieldKeyMap() keys := buildCompleteFieldKeyMap()
opts := querybuilder.FilterExprVisitorOpts{ opts := querybuilder.FilterExprVisitorOpts{
Logger: instrumentationtest.New().Logger(),
FieldMapper: fm, FieldMapper: fm,
ConditionBuilder: cb, ConditionBuilder: cb,
FieldKeys: keys, FieldKeys: keys,

View File

@ -553,6 +553,7 @@ func (b *logQueryStatementBuilder) addFilterCondition(
if query.Filter != nil && query.Filter.Expression != "" { if query.Filter != nil && query.Filter.Expression != "" {
// add filter expression // add filter expression
preparedWhereClause, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{ preparedWhereClause, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{
Logger: b.logger,
FieldMapper: b.fm, FieldMapper: b.fm,
ConditionBuilder: b.cb, ConditionBuilder: b.cb,
FieldKeys: keys, FieldKeys: keys,

View File

@ -27,6 +27,7 @@ func resourceFilterStmtBuilder() qbtypes.StatementBuilder[qbtypes.LogAggregation
mockMetadataStore.KeysMap = keysMap mockMetadataStore.KeysMap = keysMap
return resourcefilter.NewLogResourceFilterStatementBuilder( return resourcefilter.NewLogResourceFilterStatementBuilder(
instrumentationtest.New().ToProviderSettings(),
fm, fm,
cb, cb,
mockMetadataStore, mockMetadataStore,
@ -119,7 +120,7 @@ func TestStatementBuilderTimeSeries(t *testing.T) {
mockMetadataStore := telemetrytypestest.NewMockMetadataStore() mockMetadataStore := telemetrytypestest.NewMockMetadataStore()
mockMetadataStore.KeysMap = buildCompleteFieldKeyMap() mockMetadataStore.KeysMap = buildCompleteFieldKeyMap()
aggExprRewriter := querybuilder.NewAggExprRewriter(nil, fm, cb, "", nil) aggExprRewriter := querybuilder.NewAggExprRewriter(instrumentationtest.New().ToProviderSettings(), nil, fm, cb, "", nil)
resourceFilterStmtBuilder := resourceFilterStmtBuilder() resourceFilterStmtBuilder := resourceFilterStmtBuilder()
@ -212,7 +213,7 @@ func TestStatementBuilderListQuery(t *testing.T) {
mockMetadataStore := telemetrytypestest.NewMockMetadataStore() mockMetadataStore := telemetrytypestest.NewMockMetadataStore()
mockMetadataStore.KeysMap = buildCompleteFieldKeyMap() mockMetadataStore.KeysMap = buildCompleteFieldKeyMap()
aggExprRewriter := querybuilder.NewAggExprRewriter(nil, fm, cb, "", nil) aggExprRewriter := querybuilder.NewAggExprRewriter(instrumentationtest.New().ToProviderSettings(), nil, fm, cb, "", nil)
resourceFilterStmtBuilder := resourceFilterStmtBuilder() resourceFilterStmtBuilder := resourceFilterStmtBuilder()
@ -321,7 +322,7 @@ func TestStatementBuilderListQueryResourceTests(t *testing.T) {
mockMetadataStore := telemetrytypestest.NewMockMetadataStore() mockMetadataStore := telemetrytypestest.NewMockMetadataStore()
mockMetadataStore.KeysMap = buildCompleteFieldKeyMap() mockMetadataStore.KeysMap = buildCompleteFieldKeyMap()
aggExprRewriter := querybuilder.NewAggExprRewriter(nil, fm, cb, "", nil) aggExprRewriter := querybuilder.NewAggExprRewriter(instrumentationtest.New().ToProviderSettings(), nil, fm, cb, "", nil)
resourceFilterStmtBuilder := resourceFilterStmtBuilder() resourceFilterStmtBuilder := resourceFilterStmtBuilder()

View File

@ -6,4 +6,6 @@ const (
LogsV2LocalTableName = "logs_v2" LogsV2LocalTableName = "logs_v2"
TagAttributesV2TableName = "distributed_tag_attributes_v2" TagAttributesV2TableName = "distributed_tag_attributes_v2"
TagAttributesV2LocalTableName = "tag_attributes_v2" TagAttributesV2LocalTableName = "tag_attributes_v2"
LogAttributeKeysTblName = "distributed_logs_attribute_keys"
LogResourceKeysTblName = "distributed_logs_resource_keys"
) )

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"fmt" "fmt"
"log/slog" "log/slog"
"os"
"slices" "slices"
"strings" "strings"
@ -32,20 +31,23 @@ var (
) )
type telemetryMetaStore struct { type telemetryMetaStore struct {
logger *slog.Logger logger *slog.Logger
telemetrystore telemetrystore.TelemetryStore telemetrystore telemetrystore.TelemetryStore
tracesDBName string tracesDBName string
tracesFieldsTblName string tracesFieldsTblName string
indexV3TblName string spanAttributesKeysTblName string
metricsDBName string indexV3TblName string
metricsFieldsTblName string metricsDBName string
meterDBName string metricsFieldsTblName string
meterFieldsTblName string meterDBName string
logsDBName string meterFieldsTblName string
logsFieldsTblName string logsDBName string
logsV2TblName string logsFieldsTblName string
relatedMetadataDBName string logAttributeKeysTblName string
relatedMetadataTblName string logResourceKeysTblName string
logsV2TblName string
relatedMetadataDBName string
relatedMetadataTblName string
fm qbtypes.FieldMapper fm qbtypes.FieldMapper
conditionBuilder qbtypes.ConditionBuilder conditionBuilder qbtypes.ConditionBuilder
@ -60,6 +62,7 @@ func NewTelemetryMetaStore(
telemetrystore telemetrystore.TelemetryStore, telemetrystore telemetrystore.TelemetryStore,
tracesDBName string, tracesDBName string,
tracesFieldsTblName string, tracesFieldsTblName string,
spanAttributesKeysTblName string,
indexV3TblName string, indexV3TblName string,
metricsDBName string, metricsDBName string,
metricsFieldsTblName string, metricsFieldsTblName string,
@ -68,26 +71,31 @@ func NewTelemetryMetaStore(
logsDBName string, logsDBName string,
logsV2TblName string, logsV2TblName string,
logsFieldsTblName string, logsFieldsTblName string,
logAttributeKeysTblName string,
logResourceKeysTblName string,
relatedMetadataDBName string, relatedMetadataDBName string,
relatedMetadataTblName string, relatedMetadataTblName string,
) telemetrytypes.MetadataStore { ) telemetrytypes.MetadataStore {
metadataSettings := factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/pkg/telemetrymetadata") metadataSettings := factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/pkg/telemetrymetadata")
t := &telemetryMetaStore{ t := &telemetryMetaStore{
logger: metadataSettings.Logger(), logger: metadataSettings.Logger(),
telemetrystore: telemetrystore, telemetrystore: telemetrystore,
tracesDBName: tracesDBName, tracesDBName: tracesDBName,
tracesFieldsTblName: tracesFieldsTblName, tracesFieldsTblName: tracesFieldsTblName,
indexV3TblName: indexV3TblName, spanAttributesKeysTblName: spanAttributesKeysTblName,
metricsDBName: metricsDBName, indexV3TblName: indexV3TblName,
metricsFieldsTblName: metricsFieldsTblName, metricsDBName: metricsDBName,
meterDBName: meterDBName, metricsFieldsTblName: metricsFieldsTblName,
meterFieldsTblName: meterFieldsTblName, meterDBName: meterDBName,
logsDBName: logsDBName, meterFieldsTblName: meterFieldsTblName,
logsV2TblName: logsV2TblName, logsDBName: logsDBName,
logsFieldsTblName: logsFieldsTblName, logsV2TblName: logsV2TblName,
relatedMetadataDBName: relatedMetadataDBName, logsFieldsTblName: logsFieldsTblName,
relatedMetadataTblName: relatedMetadataTblName, logAttributeKeysTblName: logAttributeKeysTblName,
logResourceKeysTblName: logResourceKeysTblName,
relatedMetadataDBName: relatedMetadataDBName,
relatedMetadataTblName: relatedMetadataTblName,
} }
fm := NewFieldMapper() fm := NewFieldMapper()
@ -136,14 +144,18 @@ func (t *telemetryMetaStore) getTracesKeys(ctx context.Context, fieldKeySelector
mapOfKeys[key.Name+";"+key.FieldContext.StringValue()+";"+key.FieldDataType.StringValue()] = key mapOfKeys[key.Name+";"+key.FieldContext.StringValue()+";"+key.FieldDataType.StringValue()] = key
} }
sb := sqlbuilder.Select("tag_key", "tag_type", "tag_data_type", ` sb := sqlbuilder.Select(
CASE "tagKey AS tag_key",
WHEN tag_type = 'spanfield' THEN 1 "tagType AS tag_type",
WHEN tag_type = 'resource' THEN 2 "dataType AS tag_data_type",
WHEN tag_type = 'scope' THEN 3 `CASE
WHEN tag_type = 'tag' THEN 4 // WHEN tagType = 'spanfield' THEN 1
ELSE 5 WHEN tagType = 'resource' THEN 2
END as priority`).From(t.tracesDBName + "." + t.tracesFieldsTblName) // WHEN tagType = 'scope' THEN 3
WHEN tagType = 'tag' THEN 4
ELSE 5
END as priority`,
).From(t.tracesDBName + "." + t.spanAttributesKeysTblName)
var limit int var limit int
searchTexts := []string{} searchTexts := []string{}
@ -152,19 +164,20 @@ func (t *telemetryMetaStore) getTracesKeys(ctx context.Context, fieldKeySelector
conds := []string{} conds := []string{}
for _, fieldKeySelector := range fieldKeySelectors { for _, fieldKeySelector := range fieldKeySelectors {
if fieldKeySelector.StartUnixMilli != 0 { // TODO(srikanthccv): support time filtering for span attribute keys
conds = append(conds, sb.GE("unix_milli", fieldKeySelector.StartUnixMilli)) // if fieldKeySelector.StartUnixMilli != 0 {
} // conds = append(conds, sb.GE("unix_milli", fieldKeySelector.StartUnixMilli))
if fieldKeySelector.EndUnixMilli != 0 { // }
conds = append(conds, sb.LE("unix_milli", fieldKeySelector.EndUnixMilli)) // if fieldKeySelector.EndUnixMilli != 0 {
} // conds = append(conds, sb.LE("unix_milli", fieldKeySelector.EndUnixMilli))
// }
// key part of the selector // key part of the selector
fieldKeyConds := []string{} fieldKeyConds := []string{}
if fieldKeySelector.SelectorMatchType == telemetrytypes.FieldSelectorMatchTypeExact { if fieldKeySelector.SelectorMatchType == telemetrytypes.FieldSelectorMatchTypeExact {
fieldKeyConds = append(fieldKeyConds, sb.E("tag_key", fieldKeySelector.Name)) fieldKeyConds = append(fieldKeyConds, sb.E("tagKey", fieldKeySelector.Name))
} else { } else {
fieldKeyConds = append(fieldKeyConds, sb.ILike("tag_key", "%"+escapeForLike(fieldKeySelector.Name)+"%")) fieldKeyConds = append(fieldKeyConds, sb.ILike("tagKey", "%"+escapeForLike(fieldKeySelector.Name)+"%"))
} }
searchTexts = append(searchTexts, fieldKeySelector.Name) searchTexts = append(searchTexts, fieldKeySelector.Name)
@ -172,29 +185,25 @@ func (t *telemetryMetaStore) getTracesKeys(ctx context.Context, fieldKeySelector
dataTypes = append(dataTypes, fieldKeySelector.FieldDataType) dataTypes = append(dataTypes, fieldKeySelector.FieldDataType)
} }
// now look at the field context // now look at the field context
// we don't write most of intrinsic fields to tag attributes table // we don't write most of intrinsic fields to keys table
// for this reason we don't want to apply tag_type if the field context // for this reason we don't want to apply tagType if the field context
// if not attribute or resource attribute // is not attribute or resource attribute
if fieldKeySelector.FieldContext != telemetrytypes.FieldContextUnspecified && if fieldKeySelector.FieldContext != telemetrytypes.FieldContextUnspecified &&
(fieldKeySelector.FieldContext == telemetrytypes.FieldContextAttribute || (fieldKeySelector.FieldContext == telemetrytypes.FieldContextAttribute ||
fieldKeySelector.FieldContext == telemetrytypes.FieldContextResource) { fieldKeySelector.FieldContext == telemetrytypes.FieldContextResource) {
fieldKeyConds = append(fieldKeyConds, sb.E("tag_type", fieldKeySelector.FieldContext.TagType())) fieldKeyConds = append(fieldKeyConds, sb.E("tagType", fieldKeySelector.FieldContext.TagType()))
} }
// now look at the field data type // now look at the field data type
if fieldKeySelector.FieldDataType != telemetrytypes.FieldDataTypeUnspecified { if fieldKeySelector.FieldDataType != telemetrytypes.FieldDataTypeUnspecified {
fieldKeyConds = append(fieldKeyConds, sb.E("tag_data_type", fieldKeySelector.FieldDataType.TagDataType())) fieldKeyConds = append(fieldKeyConds, sb.E("dataType", fieldKeySelector.FieldDataType.TagDataType()))
} }
conds = append(conds, sb.And(fieldKeyConds...)) conds = append(conds, sb.And(fieldKeyConds...))
limit += fieldKeySelector.Limit limit += fieldKeySelector.Limit
if strings.TrimSpace(fieldKeySelector.Name) == "" {
sb.Limit(200)
}
} }
sb.Where(sb.Or(conds...)) sb.Where(sb.Or(conds...))
sb.GroupBy("tag_key", "tag_type", "tag_data_type") sb.GroupBy("tagKey", "tagType", "dataType")
if limit == 0 { if limit == 0 {
limit = 1000 limit = 1000
} }
@ -347,89 +356,145 @@ func (t *telemetryMetaStore) getLogsKeys(ctx context.Context, fieldKeySelectors
mapOfKeys[key.Name+";"+key.FieldContext.StringValue()+";"+key.FieldDataType.StringValue()] = key mapOfKeys[key.Name+";"+key.FieldContext.StringValue()+";"+key.FieldDataType.StringValue()] = key
} }
tblName := t.logsFieldsTblName // queries for both attribute and resource keys tables
if os.Getenv("LOGS_TAG_ATTRS_KEYS_TABLE") != "" { var queries []string
tblName = os.Getenv("LOGS_TAG_ATTRS_KEYS_TABLE") var allArgs []any
// tables to query based on field selectors
queryAttributeTable := false
queryResourceTable := false
for _, selector := range fieldKeySelectors {
if selector.FieldContext == telemetrytypes.FieldContextUnspecified {
// unspecified context, query both tables
queryAttributeTable = true
queryResourceTable = true
break
} else if selector.FieldContext == telemetrytypes.FieldContextAttribute {
queryAttributeTable = true
} else if selector.FieldContext == telemetrytypes.FieldContextResource {
queryResourceTable = true
}
} }
sb := sqlbuilder.Select("tag_key", "tag_type", "tag_data_type", ` tablesToQuery := []struct {
CASE fieldContext telemetrytypes.FieldContext
WHEN tag_type = 'logfield' THEN 1 shouldQuery bool
WHEN tag_type = 'resource' THEN 2 }{
WHEN tag_type = 'scope' THEN 3 {telemetrytypes.FieldContextAttribute, queryAttributeTable},
WHEN tag_type = 'tag' THEN 4 {telemetrytypes.FieldContextResource, queryResourceTable},
ELSE 5 }
END as priority`).From(t.logsDBName + "." + tblName)
var limit int
conds := []string{} for _, table := range tablesToQuery {
searchTexts := []string{} if !table.shouldQuery {
dataTypes := []telemetrytypes.FieldDataType{} continue
for _, fieldKeySelector := range fieldKeySelectors {
if fieldKeySelector.StartUnixMilli != 0 {
conds = append(conds, sb.GE("unix_milli", fieldKeySelector.StartUnixMilli))
}
if fieldKeySelector.EndUnixMilli != 0 {
conds = append(conds, sb.LE("unix_milli", fieldKeySelector.EndUnixMilli))
} }
// key part of the selector fieldContext := table.fieldContext
fieldKeyConds := []string{}
if fieldKeySelector.SelectorMatchType == telemetrytypes.FieldSelectorMatchTypeExact { // table name based on field context
fieldKeyConds = append(fieldKeyConds, sb.E("tag_key", fieldKeySelector.Name)) var tblName string
if fieldContext == telemetrytypes.FieldContextAttribute {
tblName = t.logsDBName + "." + t.logAttributeKeysTblName
} else { } else {
fieldKeyConds = append(fieldKeyConds, sb.ILike("tag_key", "%"+escapeForLike(fieldKeySelector.Name)+"%")) tblName = t.logsDBName + "." + t.logResourceKeysTblName
}
searchTexts = append(searchTexts, fieldKeySelector.Name)
if fieldKeySelector.FieldDataType != telemetrytypes.FieldDataTypeUnspecified {
dataTypes = append(dataTypes, fieldKeySelector.FieldDataType)
} }
// now look at the field context sb := sqlbuilder.Select(
// we don't write most of intrinsic fields to tag attributes table "name AS tag_key",
// for this reason we don't want to apply tag_type if the field context fmt.Sprintf("'%s' AS tag_type", fieldContext.TagType()),
// if not attribute or resource attribute "datatype AS tag_data_type",
if fieldKeySelector.FieldContext != telemetrytypes.FieldContextUnspecified && fmt.Sprintf(`%d AS priority`, getPriorityForContext(fieldContext)),
(fieldKeySelector.FieldContext == telemetrytypes.FieldContextAttribute || ).From(tblName)
fieldKeySelector.FieldContext == telemetrytypes.FieldContextResource) {
fieldKeyConds = append(fieldKeyConds, sb.E("tag_type", fieldKeySelector.FieldContext.TagType())) var limit int
conds := []string{}
for _, fieldKeySelector := range fieldKeySelectors {
// Include this selector if:
// 1. It has unspecified context (matches all tables)
// 2. Its context matches the current table's context
if fieldKeySelector.FieldContext != telemetrytypes.FieldContextUnspecified &&
fieldKeySelector.FieldContext != fieldContext {
continue
}
// key part of the selector
fieldKeyConds := []string{}
if fieldKeySelector.SelectorMatchType == telemetrytypes.FieldSelectorMatchTypeExact {
fieldKeyConds = append(fieldKeyConds, sb.E("name", fieldKeySelector.Name))
} else {
fieldKeyConds = append(fieldKeyConds, sb.ILike("name", "%"+escapeForLike(fieldKeySelector.Name)+"%"))
}
// now look at the field data type
if fieldKeySelector.FieldDataType != telemetrytypes.FieldDataTypeUnspecified {
fieldKeyConds = append(fieldKeyConds, sb.E("datatype", fieldKeySelector.FieldDataType.TagDataType()))
}
if len(fieldKeyConds) > 0 {
conds = append(conds, sb.And(fieldKeyConds...))
}
limit += fieldKeySelector.Limit
} }
// now look at the field data type if len(conds) > 0 {
if fieldKeySelector.FieldDataType != telemetrytypes.FieldDataTypeUnspecified { sb.Where(sb.Or(conds...))
fieldKeyConds = append(fieldKeyConds, sb.E("tag_data_type", fieldKeySelector.FieldDataType.TagDataType()))
} }
conds = append(conds, sb.And(fieldKeyConds...)) sb.GroupBy("name", "datatype")
limit += fieldKeySelector.Limit if limit == 0 {
if strings.TrimSpace(fieldKeySelector.Name) == "" { limit = 1000
sb.Limit(200)
} }
query, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
queries = append(queries, query)
allArgs = append(allArgs, args...)
}
if len(queries) == 0 {
// No matching contexts, return empty result
return []*telemetrytypes.TelemetryFieldKey{}, true, nil
}
// Combine queries with UNION ALL
var limit int
for _, fieldKeySelector := range fieldKeySelectors {
limit += fieldKeySelector.Limit
} }
sb.Where(sb.Or(conds...))
sb.GroupBy("tag_key", "tag_type", "tag_data_type")
if limit == 0 { if limit == 0 {
limit = 1000 limit = 1000
} }
mainSb := sqlbuilder.Select("tag_key", "tag_type", "tag_data_type", "max(priority) as priority") mainQuery := fmt.Sprintf(`
mainSb.From(mainSb.BuilderAs(sb, "sub_query")) SELECT tag_key, tag_type, tag_data_type, max(priority) as priority
mainSb.GroupBy("tag_key", "tag_type", "tag_data_type") FROM (
mainSb.OrderBy("priority") %s
// query one extra to check if we hit the limit ) AS combined_results
mainSb.Limit(limit + 1) GROUP BY tag_key, tag_type, tag_data_type
ORDER BY priority
LIMIT %d
`, strings.Join(queries, " UNION ALL "), limit+1)
query, args := mainSb.BuildWithFlavor(sqlbuilder.ClickHouse) rows, err := t.telemetrystore.ClickhouseDB().Query(ctx, mainQuery, allArgs...)
rows, err := t.telemetrystore.ClickhouseDB().Query(ctx, query, args...)
if err != nil { if err != nil {
return nil, false, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, ErrFailedToGetLogsKeys.Error()) return nil, false, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, ErrFailedToGetLogsKeys.Error())
} }
defer rows.Close() defer rows.Close()
keys := []*telemetrytypes.TelemetryFieldKey{} keys := []*telemetrytypes.TelemetryFieldKey{}
rowCount := 0 rowCount := 0
searchTexts := []string{}
dataTypes := []telemetrytypes.FieldDataType{}
// Collect search texts and data types for static field matching
for _, fieldKeySelector := range fieldKeySelectors {
searchTexts = append(searchTexts, fieldKeySelector.Name)
if fieldKeySelector.FieldDataType != telemetrytypes.FieldDataTypeUnspecified {
dataTypes = append(dataTypes, fieldKeySelector.FieldDataType)
}
}
for rows.Next() { for rows.Next() {
rowCount++ rowCount++
// reached the limit, we know there are more results // reached the limit, we know there are more results
@ -510,6 +575,21 @@ func (t *telemetryMetaStore) getLogsKeys(ctx context.Context, fieldKeySelectors
return keys, complete, nil return keys, complete, nil
} }
func getPriorityForContext(ctx telemetrytypes.FieldContext) int {
switch ctx {
case telemetrytypes.FieldContextLog:
return 1
case telemetrytypes.FieldContextResource:
return 2
case telemetrytypes.FieldContextScope:
return 3
case telemetrytypes.FieldContextAttribute:
return 4
default:
return 5
}
}
// getMetricsKeys returns the keys from the metrics that match the field selection criteria // getMetricsKeys returns the keys from the metrics that match the field selection criteria
func (t *telemetryMetaStore) getMetricsKeys(ctx context.Context, fieldKeySelectors []*telemetrytypes.FieldKeySelector) ([]*telemetrytypes.TelemetryFieldKey, bool, error) { func (t *telemetryMetaStore) getMetricsKeys(ctx context.Context, fieldKeySelectors []*telemetrytypes.FieldKeySelector) ([]*telemetrytypes.TelemetryFieldKey, bool, error) {
if len(fieldKeySelectors) == 0 { if len(fieldKeySelectors) == 0 {
@ -856,6 +936,7 @@ func (t *telemetryMetaStore) getRelatedValues(ctx context.Context, fieldValueSel
} }
whereClause, err := querybuilder.PrepareWhereClause(fieldValueSelector.ExistingQuery, querybuilder.FilterExprVisitorOpts{ whereClause, err := querybuilder.PrepareWhereClause(fieldValueSelector.ExistingQuery, querybuilder.FilterExprVisitorOpts{
Logger: t.logger,
FieldMapper: t.fm, FieldMapper: t.fm,
ConditionBuilder: t.conditionBuilder, ConditionBuilder: t.conditionBuilder,
FieldKeys: keys, FieldKeys: keys,

View File

@ -40,6 +40,7 @@ func TestGetKeys(t *testing.T) {
mockTelemetryStore, mockTelemetryStore,
telemetrytraces.DBName, telemetrytraces.DBName,
telemetrytraces.TagAttributesV2TableName, telemetrytraces.TagAttributesV2TableName,
telemetrytraces.SpanAttributesKeysTblName,
telemetrytraces.SpanIndexV3TableName, telemetrytraces.SpanIndexV3TableName,
telemetrymetrics.DBName, telemetrymetrics.DBName,
telemetrymetrics.AttributesMetadataTableName, telemetrymetrics.AttributesMetadataTableName,
@ -48,6 +49,8 @@ func TestGetKeys(t *testing.T) {
telemetrylogs.DBName, telemetrylogs.DBName,
telemetrylogs.LogsV2TableName, telemetrylogs.LogsV2TableName,
telemetrylogs.TagAttributesV2TableName, telemetrylogs.TagAttributesV2TableName,
telemetrylogs.LogAttributeKeysTblName,
telemetrylogs.LogResourceKeysTblName,
DBName, DBName,
AttributesMetadataLocalTableName, AttributesMetadataLocalTableName,
) )

View File

@ -141,6 +141,7 @@ func (b *meterQueryStatementBuilder) buildTemporalAggDeltaFastPath(
) )
if query.Filter != nil && query.Filter.Expression != "" { if query.Filter != nil && query.Filter.Expression != "" {
filterWhere, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{ filterWhere, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{
Logger: b.logger,
FieldMapper: b.fm, FieldMapper: b.fm,
ConditionBuilder: b.cb, ConditionBuilder: b.cb,
FieldKeys: keys, FieldKeys: keys,
@ -223,6 +224,7 @@ func (b *meterQueryStatementBuilder) buildTemporalAggDelta(
if query.Filter != nil && query.Filter.Expression != "" { if query.Filter != nil && query.Filter.Expression != "" {
filterWhere, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{ filterWhere, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{
Logger: b.logger,
FieldMapper: b.fm, FieldMapper: b.fm,
ConditionBuilder: b.cb, ConditionBuilder: b.cb,
FieldKeys: keys, FieldKeys: keys,
@ -286,6 +288,7 @@ func (b *meterQueryStatementBuilder) buildTemporalAggCumulativeOrUnspecified(
) )
if query.Filter != nil && query.Filter.Expression != "" { if query.Filter != nil && query.Filter.Expression != "" {
filterWhere, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{ filterWhere, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{
Logger: b.logger,
FieldMapper: b.fm, FieldMapper: b.fm,
ConditionBuilder: b.cb, ConditionBuilder: b.cb,
FieldKeys: keys, FieldKeys: keys,

View File

@ -68,6 +68,9 @@ func GetKeySelectors(query qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation])
for idx := range keySelectors { for idx := range keySelectors {
keySelectors[idx].Signal = telemetrytypes.SignalMetrics keySelectors[idx].Signal = telemetrytypes.SignalMetrics
keySelectors[idx].SelectorMatchType = telemetrytypes.FieldSelectorMatchTypeExact keySelectors[idx].SelectorMatchType = telemetrytypes.FieldSelectorMatchTypeExact
keySelectors[idx].MetricContext = &telemetrytypes.MetricContext{
MetricName: query.Aggregations[0].MetricName,
}
} }
return keySelectors return keySelectors
} }
@ -295,6 +298,7 @@ func (b *MetricQueryStatementBuilder) buildTimeSeriesCTE(
if query.Filter != nil && query.Filter.Expression != "" { if query.Filter != nil && query.Filter.Expression != "" {
preparedWhereClause, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{ preparedWhereClause, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{
Logger: b.logger,
FieldMapper: b.fm, FieldMapper: b.fm,
ConditionBuilder: b.cb, ConditionBuilder: b.cb,
FieldKeys: keys, FieldKeys: keys,

View File

@ -3,6 +3,7 @@ package telemetrytraces
import ( import (
"testing" "testing"
"github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest"
"github.com/SigNoz/signoz/pkg/querybuilder" "github.com/SigNoz/signoz/pkg/querybuilder"
"github.com/SigNoz/signoz/pkg/types/telemetrytypes" "github.com/SigNoz/signoz/pkg/types/telemetrytypes"
"github.com/huandu/go-sqlbuilder" "github.com/huandu/go-sqlbuilder"
@ -64,6 +65,7 @@ func TestSpanScopeFilterExpression(t *testing.T) {
}} }}
whereClause, err := querybuilder.PrepareWhereClause(tt.expression, querybuilder.FilterExprVisitorOpts{ whereClause, err := querybuilder.PrepareWhereClause(tt.expression, querybuilder.FilterExprVisitorOpts{
Logger: instrumentationtest.New().Logger(),
FieldMapper: fm, FieldMapper: fm,
ConditionBuilder: cb, ConditionBuilder: cb,
FieldKeys: fieldKeys, FieldKeys: fieldKeys,
@ -130,6 +132,7 @@ func TestSpanScopeWithResourceFilter(t *testing.T) {
}} }}
_, err := querybuilder.PrepareWhereClause(tt.expression, querybuilder.FilterExprVisitorOpts{ _, err := querybuilder.PrepareWhereClause(tt.expression, querybuilder.FilterExprVisitorOpts{
Logger: instrumentationtest.New().Logger(),
FieldMapper: fm, FieldMapper: fm,
ConditionBuilder: cb, ConditionBuilder: cb,
FieldKeys: fieldKeys, FieldKeys: fieldKeys,

View File

@ -735,6 +735,7 @@ func (b *traceQueryStatementBuilder) addFilterCondition(
if query.Filter != nil && query.Filter.Expression != "" { if query.Filter != nil && query.Filter.Expression != "" {
// add filter expression // add filter expression
preparedWhereClause, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{ preparedWhereClause, err = querybuilder.PrepareWhereClause(query.Filter.Expression, querybuilder.FilterExprVisitorOpts{
Logger: b.logger,
FieldMapper: b.fm, FieldMapper: b.fm,
ConditionBuilder: b.cb, ConditionBuilder: b.cb,
FieldKeys: keys, FieldKeys: keys,

View File

@ -21,6 +21,7 @@ func resourceFilterStmtBuilder() qbtypes.StatementBuilder[qbtypes.TraceAggregati
mockMetadataStore.KeysMap = buildCompleteFieldKeyMap() mockMetadataStore.KeysMap = buildCompleteFieldKeyMap()
return resourcefilter.NewTraceResourceFilterStatementBuilder( return resourcefilter.NewTraceResourceFilterStatementBuilder(
instrumentationtest.New().ToProviderSettings(),
fm, fm,
cb, cb,
mockMetadataStore, mockMetadataStore,
@ -327,7 +328,7 @@ func TestStatementBuilder(t *testing.T) {
cb := NewConditionBuilder(fm) cb := NewConditionBuilder(fm)
mockMetadataStore := telemetrytypestest.NewMockMetadataStore() mockMetadataStore := telemetrytypestest.NewMockMetadataStore()
mockMetadataStore.KeysMap = buildCompleteFieldKeyMap() mockMetadataStore.KeysMap = buildCompleteFieldKeyMap()
aggExprRewriter := querybuilder.NewAggExprRewriter(nil, fm, cb, "", nil) aggExprRewriter := querybuilder.NewAggExprRewriter(instrumentationtest.New().ToProviderSettings(), nil, fm, cb, "", nil)
resourceFilterStmtBuilder := resourceFilterStmtBuilder() resourceFilterStmtBuilder := resourceFilterStmtBuilder()
@ -495,7 +496,7 @@ func TestStatementBuilderListQuery(t *testing.T) {
cb := NewConditionBuilder(fm) cb := NewConditionBuilder(fm)
mockMetadataStore := telemetrytypestest.NewMockMetadataStore() mockMetadataStore := telemetrytypestest.NewMockMetadataStore()
mockMetadataStore.KeysMap = buildCompleteFieldKeyMap() mockMetadataStore.KeysMap = buildCompleteFieldKeyMap()
aggExprRewriter := querybuilder.NewAggExprRewriter(nil, fm, cb, "", nil) aggExprRewriter := querybuilder.NewAggExprRewriter(instrumentationtest.New().ToProviderSettings(), nil, fm, cb, "", nil)
resourceFilterStmtBuilder := resourceFilterStmtBuilder() resourceFilterStmtBuilder := resourceFilterStmtBuilder()
@ -557,7 +558,7 @@ func TestStatementBuilderTraceQuery(t *testing.T) {
cb := NewConditionBuilder(fm) cb := NewConditionBuilder(fm)
mockMetadataStore := telemetrytypestest.NewMockMetadataStore() mockMetadataStore := telemetrytypestest.NewMockMetadataStore()
mockMetadataStore.KeysMap = buildCompleteFieldKeyMap() mockMetadataStore.KeysMap = buildCompleteFieldKeyMap()
aggExprRewriter := querybuilder.NewAggExprRewriter(nil, fm, cb, "", nil) aggExprRewriter := querybuilder.NewAggExprRewriter(instrumentationtest.New().ToProviderSettings(), nil, fm, cb, "", nil)
resourceFilterStmtBuilder := resourceFilterStmtBuilder() resourceFilterStmtBuilder := resourceFilterStmtBuilder()

View File

@ -8,4 +8,5 @@ const (
TagAttributesV2LocalTableName = "tag_attributes_v2" TagAttributesV2LocalTableName = "tag_attributes_v2"
TopLevelOperationsTableName = "distributed_top_level_operations" TopLevelOperationsTableName = "distributed_top_level_operations"
TraceSummaryTableName = "distributed_trace_summary" TraceSummaryTableName = "distributed_trace_summary"
SpanAttributesKeysTblName = "distributed_span_attributes_keys"
) )

View File

@ -38,12 +38,13 @@ func TestTraceTimeRangeOptimization(t *testing.T) {
resourceFilterFM := resourcefilter.NewFieldMapper() resourceFilterFM := resourcefilter.NewFieldMapper()
resourceFilterCB := resourcefilter.NewConditionBuilder(resourceFilterFM) resourceFilterCB := resourcefilter.NewConditionBuilder(resourceFilterFM)
resourceFilterStmtBuilder := resourcefilter.NewTraceResourceFilterStatementBuilder( resourceFilterStmtBuilder := resourcefilter.NewTraceResourceFilterStatementBuilder(
instrumentationtest.New().ToProviderSettings(),
resourceFilterFM, resourceFilterFM,
resourceFilterCB, resourceFilterCB,
mockMetadataStore, mockMetadataStore,
) )
aggExprRewriter := querybuilder.NewAggExprRewriter(nil, fm, cb, "", nil) aggExprRewriter := querybuilder.NewAggExprRewriter(instrumentationtest.New().ToProviderSettings(), nil, fm, cb, "", nil)
statementBuilder := NewTraceQueryStatementBuilder( statementBuilder := NewTraceQueryStatementBuilder(
instrumentationtest.New().ToProviderSettings(), instrumentationtest.New().ToProviderSettings(),