mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-17 15:36:48 +00:00
Merge branch 'trace_operator_implementation' into demo/trace_operators_backend
This commit is contained in:
commit
7206bb82fe
@ -434,7 +434,26 @@ func (b *traceOperatorCTEBuilder) buildListQuery(selectFromCTE string) (*qbtypes
|
|||||||
|
|
||||||
sb.From(selectFromCTE)
|
sb.From(selectFromCTE)
|
||||||
|
|
||||||
|
// Add order by support
|
||||||
|
keySelectors := b.getKeySelectors()
|
||||||
|
keys, _, err := b.stmtBuilder.metadataStore.GetKeysMulti(b.ctx, keySelectors)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
orderApplied := false
|
||||||
|
for _, orderBy := range b.operator.Order {
|
||||||
|
colExpr, err := b.stmtBuilder.fm.ColumnExpressionFor(b.ctx, &orderBy.Key.TelemetryFieldKey, keys)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sb.OrderBy(fmt.Sprintf("%s %s", colExpr, orderBy.Direction.StringValue()))
|
||||||
|
orderApplied = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !orderApplied {
|
||||||
sb.OrderBy("timestamp DESC")
|
sb.OrderBy("timestamp DESC")
|
||||||
|
}
|
||||||
|
|
||||||
if b.operator.Limit > 0 {
|
if b.operator.Limit > 0 {
|
||||||
sb.Limit(b.operator.Limit)
|
sb.Limit(b.operator.Limit)
|
||||||
@ -442,6 +461,10 @@ func (b *traceOperatorCTEBuilder) buildListQuery(selectFromCTE string) (*qbtypes
|
|||||||
sb.Limit(100)
|
sb.Limit(100)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.operator.Offset > 0 {
|
||||||
|
sb.Offset(b.operator.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
sql, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
sql, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||||
return &qbtypes.Statement{
|
return &qbtypes.Statement{
|
||||||
Query: sql,
|
Query: sql,
|
||||||
@ -630,6 +653,17 @@ func (b *traceOperatorCTEBuilder) buildTimeSeriesQuery(selectFromCTE string) (*q
|
|||||||
sb.GroupBy(groupByKeys...)
|
sb.GroupBy(groupByKeys...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add order by support
|
||||||
|
for _, orderBy := range b.operator.Order {
|
||||||
|
idx, ok := b.aggOrderBy(orderBy)
|
||||||
|
if ok {
|
||||||
|
sb.OrderBy(fmt.Sprintf("__result_%d %s", idx, orderBy.Direction.StringValue()))
|
||||||
|
} else {
|
||||||
|
sb.OrderBy(fmt.Sprintf("`%s` %s", orderBy.Key.Name, orderBy.Direction.StringValue()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.OrderBy("ts desc")
|
||||||
|
|
||||||
combinedArgs := append(allGroupByArgs, allAggChArgs...)
|
combinedArgs := append(allGroupByArgs, allAggChArgs...)
|
||||||
|
|
||||||
// Add HAVING clause if specified
|
// Add HAVING clause if specified
|
||||||
@ -637,6 +671,11 @@ func (b *traceOperatorCTEBuilder) buildTimeSeriesQuery(selectFromCTE string) (*q
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add limit support
|
||||||
|
if b.operator.Limit > 0 {
|
||||||
|
sb.Limit(b.operator.Limit)
|
||||||
|
}
|
||||||
|
|
||||||
sql, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse, combinedArgs...)
|
sql, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse, combinedArgs...)
|
||||||
return &qbtypes.Statement{
|
return &qbtypes.Statement{
|
||||||
Query: sql,
|
Query: sql,
|
||||||
@ -855,6 +894,26 @@ func (b *traceOperatorCTEBuilder) buildScalarQuery(selectFromCTE string) (*qbtyp
|
|||||||
sb.GroupBy(groupByKeys...)
|
sb.GroupBy(groupByKeys...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add order by support
|
||||||
|
for _, orderBy := range b.operator.Order {
|
||||||
|
idx, ok := b.aggOrderBy(orderBy)
|
||||||
|
if ok {
|
||||||
|
sb.OrderBy(fmt.Sprintf("__result_%d %s", idx, orderBy.Direction.StringValue()))
|
||||||
|
} else {
|
||||||
|
sb.OrderBy(fmt.Sprintf("`%s` %s", orderBy.Key.Name, orderBy.Direction.StringValue()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add default ordering if no orderBy specified
|
||||||
|
if len(b.operator.Order) == 0 {
|
||||||
|
sb.OrderBy("__result_0 DESC")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add limit support
|
||||||
|
if b.operator.Limit > 0 {
|
||||||
|
sb.Limit(b.operator.Limit)
|
||||||
|
}
|
||||||
|
|
||||||
combinedArgs := append(allGroupByArgs, allAggChArgs...)
|
combinedArgs := append(allGroupByArgs, allAggChArgs...)
|
||||||
|
|
||||||
// Add HAVING clause if specified
|
// Add HAVING clause if specified
|
||||||
@ -887,3 +946,14 @@ func (b *traceOperatorCTEBuilder) addCTE(name, sql string, args []any, dependsOn
|
|||||||
})
|
})
|
||||||
b.cteNameToIndex[name] = len(b.ctes) - 1
|
b.cteNameToIndex[name] = len(b.ctes) - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *traceOperatorCTEBuilder) aggOrderBy(k qbtypes.OrderBy) (int, bool) {
|
||||||
|
for i, agg := range b.operator.Aggregations {
|
||||||
|
if k.Key.Name == agg.Alias ||
|
||||||
|
k.Key.Name == agg.Expression ||
|
||||||
|
k.Key.Name == fmt.Sprintf("__result_%d", i) {
|
||||||
|
return i, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|||||||
@ -56,6 +56,7 @@ type QueryBuilderTraceOperator struct {
|
|||||||
Having *Having `json:"having,omitempty"`
|
Having *Having `json:"having,omitempty"`
|
||||||
|
|
||||||
Limit int `json:"limit,omitempty"`
|
Limit int `json:"limit,omitempty"`
|
||||||
|
Offset int `json:"offset,omitempty"`
|
||||||
Cursor string `json:"cursor,omitempty"`
|
Cursor string `json:"cursor,omitempty"`
|
||||||
|
|
||||||
Legend string `json:"legend,omitempty"`
|
Legend string `json:"legend,omitempty"`
|
||||||
@ -264,6 +265,15 @@ func (q *QueryBuilderTraceOperator) ValidatePagination() error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if q.Offset < 0 {
|
||||||
|
return errors.WrapInvalidInputf(
|
||||||
|
nil,
|
||||||
|
errors.CodeInvalidInput,
|
||||||
|
"offset must be non-negative, got %d",
|
||||||
|
q.Offset,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// For production use, you might want to enforce maximum limits
|
// For production use, you might want to enforce maximum limits
|
||||||
if q.Limit > 10000 {
|
if q.Limit > 10000 {
|
||||||
return errors.WrapInvalidInputf(
|
return errors.WrapInvalidInputf(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user