diff --git a/src/data/adHocFilter.test.ts b/src/data/adHocFilter.test.ts index b78de82b..367804ef 100644 --- a/src/data/adHocFilter.test.ts +++ b/src/data/adHocFilter.test.ts @@ -163,6 +163,17 @@ describe('AdHocManager', () => { ); }); + it('apply ad hoc filter IN operator without parentheses', () => { + const ahm = new AdHocFilter(); + ahm.setTargetTableFromQuery('SELECT * FROM foo'); + const val = ahm.apply('SELECT stuff FROM foo WHERE col = test', [ + { key: 'key', operator: 'IN', value: '\'val1\', \'val2\'' }, + ] as AdHocVariableFilter[]); + expect(val).toEqual( + `SELECT stuff FROM foo WHERE col = test settings additional_table_filters={'foo' : ' key IN (\\'val1\\', \\'val2\\') '}` + ); + }); + it('apply ad hoc filter IN operator with integer values', () => { const ahm = new AdHocFilter(); ahm.setTargetTableFromQuery('SELECT * FROM foo'); diff --git a/src/data/adHocFilter.ts b/src/data/adHocFilter.ts index 58457824..eadb8927 100644 --- a/src/data/adHocFilter.ts +++ b/src/data/adHocFilter.ts @@ -60,10 +60,15 @@ function isValid(filter: AdHocVariableFilter): boolean { function escapeValueBasedOnOperator(s: string, operator: AdHocVariableFilterOperator): string { if (operator === 'IN') { - return `${s}`.replace(/'/g, "\\'"); - } + // Allow list of values without parentheses + if (s.length > 2 && s[0] !== '(' && s[s.length - 1] !== ')') { + s = `(${s})` + } - return `\\'${s}\\'`; + return s.replace(/'/g, "\\'"); + } else { + return `\\'${s}\\'`; + } } function convertOperatorToClickHouseOperator(operator: AdHocVariableFilterOperator): string {