Skip to content

Commit 16c52ea

Browse files
authored
fix(streaming): group by order for raw event connector (#1987)
1 parent 68cbb6b commit 16c52ea

File tree

2 files changed

+12
-13
lines changed

2 files changed

+12
-13
lines changed

openmeter/streaming/clickhouse/raw_events/connector.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"fmt"
77
"log/slog"
8+
"sort"
89
"strings"
910
"time"
1011

@@ -337,6 +338,11 @@ func (c *Connector) queryCountEvents(ctx context.Context, namespace string, para
337338
}
338339

339340
func (c *Connector) queryMeter(ctx context.Context, namespace string, meter models.Meter, params streaming.QueryParams) ([]models.MeterQueryRow, error) {
341+
// We sort the group by keys to ensure the order of the group by columns is deterministic
342+
// It helps testing the SQL queries.
343+
groupBy := params.GroupBy
344+
sort.Strings(groupBy)
345+
340346
queryMeter := queryMeter{
341347
Database: c.config.Database,
342348
EventsTableName: c.config.EventsTableName,
@@ -346,7 +352,7 @@ func (c *Connector) queryMeter(ctx context.Context, namespace string, meter mode
346352
To: params.To,
347353
Subject: params.FilterSubject,
348354
FilterGroupBy: params.FilterGroupBy,
349-
GroupBy: params.GroupBy,
355+
GroupBy: groupBy,
350356
WindowSize: params.WindowSize,
351357
WindowTimeZone: params.WindowTimeZone,
352358
}
@@ -393,6 +399,7 @@ func (c *Connector) queryMeter(ctx context.Context, namespace string, meter mode
393399

394400
for i, key := range queryMeter.GroupBy {
395401
if s, ok := args[i+argCount].(*string); ok {
402+
// Subject is a top level field
396403
if key == "subject" {
397404
row.Subject = s
398405
continue

openmeter/streaming/clickhouse/raw_events/meter_query.go

+4-12
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package raw_events
33
import (
44
_ "embed"
55
"fmt"
6-
"slices"
76
"sort"
87
"time"
98

@@ -105,22 +104,15 @@ func (d queryMeter) toSQL() (string, []interface{}, error) {
105104
selectColumns = append(selectColumns, fmt.Sprintf("%s(cast(JSON_VALUE(%s, '%s'), 'Float64')) AS value", sqlAggregation, getColumn("data"), sqlbuilder.Escape(d.Meter.ValueProperty)))
106105
}
107106

108-
groupBys := make([]string, 0, len(d.GroupBy))
109-
110-
for _, groupBy := range d.GroupBy {
111-
if groupBy == "subject" {
107+
for _, groupByKey := range d.GroupBy {
108+
// Subject is a special case as it's a top level column
109+
if groupByKey == "subject" {
112110
selectColumns = append(selectColumns, getColumn("subject"))
113111
groupByColumns = append(groupByColumns, "subject")
114112
continue
115113
}
116114

117-
groupBys = append(groupBys, groupBy)
118-
}
119-
120-
// Select Group By
121-
slices.Sort(groupBys)
122-
123-
for _, groupByKey := range groupBys {
115+
// Group by columns need to be parsed from the JSON data
124116
groupByColumn := sqlbuilder.Escape(groupByKey)
125117
groupByJSONPath := sqlbuilder.Escape(d.Meter.GroupBy[groupByKey])
126118
selectColumn := fmt.Sprintf("JSON_VALUE(%s, '%s') as %s", getColumn("data"), groupByJSONPath, groupByColumn)

0 commit comments

Comments
 (0)