fix: Skip rendering empty SQL dashboard filter (#2115)

## Summary

This PR fixes a bug causing the $__filters macro to error when the dashboard's global SQL filter is an empty string or whitespace only.

### Screenshots or video

Before: an empty string in the SQL filter box would cause $__filters to render as `(())`

<img width="1708" height="1042" alt="Screenshot 2026-04-14 at 1 29 41 PM" src="https://github.com/user-attachments/assets/0a4068ad-eaf2-4bf7-b894-b796f642b59a" />


After: the empty SQL filter is ignored

<img width="2330" height="520" alt="Screenshot 2026-04-14 at 1 29 20 PM" src="https://github.com/user-attachments/assets/a1e83091-5522-4745-b717-f1bf51c84a80" />


### How to test locally or on Vercel

This can be tested in the preview environment

### References



- Linear Issue: Closes HDX-4017
- Related PRs:
This commit is contained in:
Drew Davis 2026-04-14 16:04:58 -04:00 committed by GitHub
parent 28f374ef12
commit cc714f909a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 27 additions and 1 deletions

View file

@ -0,0 +1,5 @@
---
"@hyperdx/common-utils": patch
---
fix: Skip rendering empty SQL dashboard filter

View file

@ -1989,6 +1989,25 @@ describe('renderChartConfig', () => {
);
});
it('skips empty sql filters when source has no tableName (metric source)', async () => {
const result = await renderChartConfig(
{
configType: 'sql',
sqlTemplate: 'SELECT * FROM logs WHERE $__filters',
connection: 'conn-1',
dateRange: [start, end],
source: 'source-1',
from: { databaseName: 'default', tableName: '' },
filters: [{ type: 'sql', condition: '' }],
},
mockMetadata,
undefined,
);
expect(result.sql).toBe(
'SELECT * FROM logs WHERE (1=1 /** no filters applied */)',
);
});
it('skips filters without source metadata (no from)', async () => {
const result = await renderChartConfig(
{

View file

@ -1542,7 +1542,9 @@ async function renderFiltersToSql(
if (filter.type === 'sql_ast') {
return `(${filter.left} ${filter.operator} ${filter.right})`;
} else if (filter.type === 'sql' && !hasSourceTable) {
return `(${filter.condition})`; // Don't pass to renderWhereExpressionStr since it requires source table metadata
return filter.condition.trim()
? `(${filter.condition})` // Don't pass to renderWhereExpressionStr since it requires source table metadata
: undefined;
} else if (
(filter.type === 'lucene' || filter.type === 'sql') &&
filter.condition.trim() &&