hyperdx/packages/common-utils/src/rawSqlParams.ts
Drew Davis fd9f290e2a
feat: Add query params, sorting, and placeholders to Raw-SQL tables (#1857)
Closes HDX-3580
Closes HDX-3034

## Summary

This PR enhances the support for SQL-driven tables

1. The selected date range can now be referenced in the query with query params. The available query params are outlined in a new section above the SQL input.
2. The table no longer OOMs on large result sets (it is now truncated to the first 10k results), or crashes when selecting columns that are Map or JSON type
3. The table can now be sorted client-side for sql-driven tables
4. There is now placeholder / example SQL in the input

### Screenshots or video

https://github.com/user-attachments/assets/4f39fd0a-d33e-4f8c-9e91-84143d23e293

### How to test locally or on Vercel

This feature can be tested locally or on the preview environment without any special toggles.

### References



- Linear Issue: HDX-3580
- Related PRs:
2026-03-06 16:05:34 +00:00

60 lines
1.8 KiB
TypeScript

import { ChSql } from './clickhouse';
import { DateRange, DisplayType, RawSqlChartConfig } from './types';
type QueryParamDefinition = {
name: string;
type: string;
description: string;
get: (config: RawSqlChartConfig & Partial<DateRange>) => any;
};
export const QUERY_PARAMS: Record<string, QueryParamDefinition> = {
startDateMilliseconds: {
name: 'startDateMilliseconds',
type: 'Int64',
description:
'start of the dashboard date range, in milliseconds since epoch',
get: (config: RawSqlChartConfig & Partial<DateRange>) =>
config.dateRange ? config.dateRange[0].getTime() : undefined,
},
endDateMilliseconds: {
name: 'endDateMilliseconds',
type: 'Int64',
description: 'end of the dashboard date range, in milliseconds since epoch',
get: (config: RawSqlChartConfig & Partial<DateRange>) =>
config.dateRange ? config.dateRange[1].getTime() : undefined,
},
};
export const QUERY_PARAMS_BY_DISPLAY_TYPE: Record<
DisplayType,
QueryParamDefinition[]
> = {
[DisplayType.Line]: [],
[DisplayType.StackedBar]: [],
[DisplayType.Table]: [
QUERY_PARAMS.startDateMilliseconds,
QUERY_PARAMS.endDateMilliseconds,
],
[DisplayType.Pie]: [],
[DisplayType.Number]: [],
[DisplayType.Search]: [],
[DisplayType.Heatmap]: [],
[DisplayType.Markdown]: [],
};
export function renderRawSqlChartConfig(
chartConfig: RawSqlChartConfig & Partial<DateRange>,
): ChSql {
const displayType = chartConfig.displayType ?? DisplayType.Table;
// eslint-disable-next-line security/detect-object-injection
const queryParams = QUERY_PARAMS_BY_DISPLAY_TYPE[displayType];
return {
sql: chartConfig.sqlTemplate ?? '',
params: Object.fromEntries(
queryParams.map(param => [param.name, param.get(chartConfig)]),
),
};
}