Skip to content

Commit 33096cf

Browse files
committed
(fix): handle JSON columns in db statement expressions
1 parent bd344b3 commit 33096cf

File tree

3 files changed

+38
-16
lines changed

3 files changed

+38
-16
lines changed

packages/app/src/components/ServiceDashboardEndpointPerformanceChart.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,22 @@ export default function ServiceDashboardEndpointPerformanceChart({
6868
// existence of the serverAddress/httpHost to build the span name
6969
if (jsonColumns.includes(spanAttributesExpression)) {
7070
spanNameColSql = `
71-
concat(
72-
${expressions.spanName}, ' ',
73-
if(
74-
has(['HTTP DELETE', 'DELETE', 'HTTP GET', 'GET', 'HTTP HEAD', 'HEAD', 'HTTP OPTIONS', 'OPTIONS', 'HTTP PATCH', 'PATCH', 'HTTP POST', 'POST', 'HTTP PUT', 'PUT'], ${expressions.spanName}),
71+
concat(
72+
${expressions.spanName}, ' ',
7573
if(
76-
toString(${expressions.serverAddress}) != '',
77-
toString(${expressions.serverAddress}),
78-
if(
79-
toString(${expressions.httpHost}) != '',
80-
toString(${expressions.httpHost}),
81-
''
82-
)
83-
),
84-
''
85-
))`;
74+
has(['HTTP DELETE', 'DELETE', 'HTTP GET', 'GET', 'HTTP HEAD', 'HEAD', 'HTTP OPTIONS', 'OPTIONS', 'HTTP PATCH', 'PATCH', 'HTTP POST', 'POST', 'HTTP PUT', 'PUT'], ${expressions.spanName}),
75+
if(
76+
toString(${expressions.serverAddress}) != '',
77+
toString(${expressions.serverAddress}),
78+
if(
79+
toString(${expressions.httpHost}) != '',
80+
toString(${expressions.httpHost}),
81+
''
82+
)
83+
),
84+
''
85+
)
86+
)`;
8687
}
8788

8889
return (

packages/app/src/serviceDashboard.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ function getDefaults(jsonColumns: string[] = []) {
44
const spanAttributeField = 'SpanAttributes';
55
const isJsonColumn = jsonColumns.includes(spanAttributeField);
66

7-
// Helper function to format field access based on column type
87
const formatFieldAccess = (field: string, key: string) => {
98
if (isJsonColumn) {
109
return `${field}.\`${key}\``;
@@ -13,6 +12,27 @@ function getDefaults(jsonColumns: string[] = []) {
1312
}
1413
};
1514

15+
let dbStatement = `coalesce(nullif(${formatFieldAccess(spanAttributeField, 'db.query.text')}, ''), nullif(${formatFieldAccess(spanAttributeField, 'db.statement')}, ''))`;
16+
17+
// ClickHouse does not support NULLIF(some_dynamic_column)
18+
// so we instead use toString() and an empty string check to check for
19+
// existence of the serverAddress/httpHost to build the span name
20+
if (isJsonColumn) {
21+
dbStatement = `
22+
coalesce(
23+
if(
24+
toString(${formatFieldAccess(spanAttributeField, 'db.query.text')}) != '',
25+
toString(${formatFieldAccess(spanAttributeField, 'db.query.text')}),
26+
if(
27+
toString(${formatFieldAccess(spanAttributeField, 'db.statement')}) != '',
28+
toString(${formatFieldAccess(spanAttributeField, 'db.statement')}),
29+
''
30+
)
31+
)
32+
)
33+
`;
34+
}
35+
1636
return {
1737
duration: 'Duration',
1838
durationPrecision: 9,
@@ -26,7 +46,7 @@ function getDefaults(jsonColumns: string[] = []) {
2646
httpScheme: formatFieldAccess(spanAttributeField, 'http.scheme'),
2747
serverAddress: formatFieldAccess(spanAttributeField, 'server.address'),
2848
httpHost: formatFieldAccess(spanAttributeField, 'http.host'),
29-
dbStatement: `coalesce(nullif(${formatFieldAccess(spanAttributeField, 'db.query.text')}, ''), nullif(${formatFieldAccess(spanAttributeField, 'db.statement')}, ''))`,
49+
dbStatement,
3050
};
3151
}
3252

packages/common-utils/src/metadata.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export class Metadata {
162162
connectionId,
163163
});
164164

165+
// TODO: should we use .includes() to handle Array(JSON) and other variants?
165166
return columns
166167
.filter(column => column.type.startsWith('JSON'))
167168
.map(column => column.name);

0 commit comments

Comments
 (0)