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"
@ -36,6 +35,7 @@ type telemetryMetaStore struct {
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
@ -43,6 +43,8 @@ type telemetryMetaStore struct {
meterFieldsTblName string meterFieldsTblName string
logsDBName string logsDBName string
logsFieldsTblName string logsFieldsTblName string
logAttributeKeysTblName string
logResourceKeysTblName string
logsV2TblName string logsV2TblName string
relatedMetadataDBName string relatedMetadataDBName string
relatedMetadataTblName string relatedMetadataTblName string
@ -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,6 +71,8 @@ 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 {
@ -78,6 +83,7 @@ func NewTelemetryMetaStore(
telemetrystore: telemetrystore, telemetrystore: telemetrystore,
tracesDBName: tracesDBName, tracesDBName: tracesDBName,
tracesFieldsTblName: tracesFieldsTblName, tracesFieldsTblName: tracesFieldsTblName,
spanAttributesKeysTblName: spanAttributesKeysTblName,
indexV3TblName: indexV3TblName, indexV3TblName: indexV3TblName,
metricsDBName: metricsDBName, metricsDBName: metricsDBName,
metricsFieldsTblName: metricsFieldsTblName, metricsFieldsTblName: metricsFieldsTblName,
@ -86,6 +92,8 @@ func NewTelemetryMetaStore(
logsDBName: logsDBName, logsDBName: logsDBName,
logsV2TblName: logsV2TblName, logsV2TblName: logsV2TblName,
logsFieldsTblName: logsFieldsTblName, logsFieldsTblName: logsFieldsTblName,
logAttributeKeysTblName: logAttributeKeysTblName,
logResourceKeysTblName: logResourceKeysTblName,
relatedMetadataDBName: relatedMetadataDBName, relatedMetadataDBName: relatedMetadataDBName,
relatedMetadataTblName: relatedMetadataTblName, relatedMetadataTblName: relatedMetadataTblName,
} }
@ -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
WHEN tagType = 'resource' THEN 2
// WHEN tagType = 'scope' THEN 3
WHEN tagType = 'tag' THEN 4
ELSE 5 ELSE 5
END as priority`).From(t.tracesDBName + "." + t.tracesFieldsTblName) 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
for _, table := range tablesToQuery {
if !table.shouldQuery {
continue
}
fieldContext := table.fieldContext
// table name based on field context
var tblName string
if fieldContext == telemetrytypes.FieldContextAttribute {
tblName = t.logsDBName + "." + t.logAttributeKeysTblName
} else {
tblName = t.logsDBName + "." + t.logResourceKeysTblName
}
sb := sqlbuilder.Select(
"name AS tag_key",
fmt.Sprintf("'%s' AS tag_type", fieldContext.TagType()),
"datatype AS tag_data_type",
fmt.Sprintf(`%d AS priority`, getPriorityForContext(fieldContext)),
).From(tblName)
var limit int
conds := []string{} conds := []string{}
searchTexts := []string{}
dataTypes := []telemetrytypes.FieldDataType{}
for _, fieldKeySelector := range fieldKeySelectors { for _, fieldKeySelector := range fieldKeySelectors {
// Include this selector if:
if fieldKeySelector.StartUnixMilli != 0 { // 1. It has unspecified context (matches all tables)
conds = append(conds, sb.GE("unix_milli", fieldKeySelector.StartUnixMilli)) // 2. Its context matches the current table's context
} if fieldKeySelector.FieldContext != telemetrytypes.FieldContextUnspecified &&
if fieldKeySelector.EndUnixMilli != 0 { fieldKeySelector.FieldContext != fieldContext {
conds = append(conds, sb.LE("unix_milli", fieldKeySelector.EndUnixMilli)) continue
} }
// 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("name", fieldKeySelector.Name))
} else { } else {
fieldKeyConds = append(fieldKeyConds, sb.ILike("tag_key", "%"+escapeForLike(fieldKeySelector.Name)+"%")) fieldKeyConds = append(fieldKeyConds, sb.ILike("name", "%"+escapeForLike(fieldKeySelector.Name)+"%"))
}
searchTexts = append(searchTexts, fieldKeySelector.Name)
if fieldKeySelector.FieldDataType != telemetrytypes.FieldDataTypeUnspecified {
dataTypes = append(dataTypes, fieldKeySelector.FieldDataType)
}
// now look at the field context
// we don't write most of intrinsic fields to tag attributes table
// for this reason we don't want to apply tag_type if the field context
// if not attribute or resource attribute
if fieldKeySelector.FieldContext != telemetrytypes.FieldContextUnspecified &&
(fieldKeySelector.FieldContext == telemetrytypes.FieldContextAttribute ||
fieldKeySelector.FieldContext == telemetrytypes.FieldContextResource) {
fieldKeyConds = append(fieldKeyConds, sb.E("tag_type", 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()))
} }
if len(fieldKeyConds) > 0 {
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)
}
} }
if len(conds) > 0 {
sb.Where(sb.Or(conds...)) sb.Where(sb.Or(conds...))
sb.GroupBy("tag_key", "tag_type", "tag_data_type") }
sb.GroupBy("name", "datatype")
if limit == 0 { if limit == 0 {
limit = 1000 limit = 1000
} }
mainSb := sqlbuilder.Select("tag_key", "tag_type", "tag_data_type", "max(priority) as priority") query, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
mainSb.From(mainSb.BuilderAs(sb, "sub_query")) queries = append(queries, query)
mainSb.GroupBy("tag_key", "tag_type", "tag_data_type") allArgs = append(allArgs, args...)
mainSb.OrderBy("priority") }
// query one extra to check if we hit the limit
mainSb.Limit(limit + 1)
query, args := mainSb.BuildWithFlavor(sqlbuilder.ClickHouse) if len(queries) == 0 {
// No matching contexts, return empty result
return []*telemetrytypes.TelemetryFieldKey{}, true, nil
}
rows, err := t.telemetrystore.ClickhouseDB().Query(ctx, query, args...) // Combine queries with UNION ALL
var limit int
for _, fieldKeySelector := range fieldKeySelectors {
limit += fieldKeySelector.Limit
}
if limit == 0 {
limit = 1000
}
mainQuery := fmt.Sprintf(`
SELECT tag_key, tag_type, tag_data_type, max(priority) as priority
FROM (
%s
) AS combined_results
GROUP BY tag_key, tag_type, tag_data_type
ORDER BY priority
LIMIT %d
`, strings.Join(queries, " UNION ALL "), limit+1)
rows, err := t.telemetrystore.ClickhouseDB().Query(ctx, mainQuery, allArgs...)
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(),