Skip to content

Commit

Permalink
do not create malformed adhoc filters (#451)
Browse files Browse the repository at this point in the history
  • Loading branch information
mshustov authored and alyssabull committed Aug 10, 2023
1 parent 5fc64e9 commit 1f50576
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
43 changes: 43 additions & 0 deletions src/data/adHocFilter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,47 @@ describe('AdHocManager', () => {
`SELECT stuff FROM foo WHERE col = test settings additional_table_filters={'foo' : ' key NOT ILIKE \\'val\\' '}`
);
});

it('does not apply an adhoc filter without "operator"', () => {
const ahm = new AdHocFilter();
ahm.setTargetTableFromQuery('SELECT * FROM foo');
const val = ahm.apply('SELECT foo.stuff FROM foo', [
// @ts-expect-error
{ key: 'foo.key', operator: undefined, value: 'val' },
]);
expect(val).toEqual(`SELECT foo.stuff FROM foo`);
});

it('does not apply an adhoc filter without "value"', () => {
const ahm = new AdHocFilter();
ahm.setTargetTableFromQuery('SELECT * FROM foo');
const val = ahm.apply('SELECT foo.stuff FROM foo', [
// @ts-expect-error
{ key: 'foo.key', operator: '=', value: undefined },
]);
expect(val).toEqual(`SELECT foo.stuff FROM foo`);
});

it('does not apply an adhoc filter without "key"', () => {
const ahm = new AdHocFilter();
ahm.setTargetTableFromQuery('SELECT * FROM foo');
const val = ahm.apply('SELECT foo.stuff FROM foo', [
// @ts-expect-error
{ key: undefined, operator: '=', value: 'val' },
]);
expect(val).toEqual(`SELECT foo.stuff FROM foo`);
});

it('log a malformed filter', () => {
const warn = jest.spyOn(console, "error");
const value = { key: 'foo.key', operator: '=', value: undefined }
const ahm = new AdHocFilter();
ahm.setTargetTableFromQuery('SELECT * FROM foo');
ahm.apply('SELECT foo.stuff FROM foo', [
// @ts-expect-error
value,
]);
expect(warn).toHaveBeenCalledTimes(1);
expect(warn).toHaveBeenCalledWith("Invalid adhoc filter will be ignored:", value)
});
});
21 changes: 19 additions & 2 deletions src/data/adHocFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,22 @@ export class AdHocFilter {
return sql;
}
const filter = adHocFilters[0];
if (filter.key.includes('.')) {

if (filter.key?.includes('.')) {
this._targetTable = filter.key.split('.')[0];
}
if (this._targetTable === '' || !sql.match(new RegExp(`.*\\b${this._targetTable}\\b.*`, 'gi'))) {
return sql;
}

const filters = adHocFilters
.filter((filter: AdHocVariableFilter) => {
const valid = isValid(filter);
if(!valid) {
console.error('Invalid adhoc filter will be ignored:', filter);
}
return valid;
})
.map((f, i) => {
const key = f.key.includes('.') ? f.key.split('.')[1] : f.key;
const value = isNaN(Number(f.value)) ? `\\'${f.value}\\'` : Number(f.value);
Expand All @@ -35,12 +44,20 @@ export class AdHocFilter {
return ` ${key} ${operator} ${value} ${condition}`;
})
.join('');

if(filters === '') {
return sql;
}
// Semicolons are not required and cause problems when building the SQL
sql = sql.replace(';', '');
return `${sql} settings additional_table_filters={'${this._targetTable}' : '${filters}'}`;
}
}

function isValid(filter: AdHocVariableFilter): boolean {
return filter.key !== undefined && filter.operator !== undefined && filter.value !== undefined;
}

function convertOperatorToClickHouseOperator(operator: AdHocVariableFilterOperator): string {
if (operator === '=~') {return 'ILIKE';}
if (operator === '!~') {return 'NOT ILIKE';}
Expand All @@ -53,5 +70,5 @@ export type AdHocVariableFilter = {
key: string;
operator: AdHocVariableFilterOperator;
value: string;
condition: string;
condition?: string;
};

0 comments on commit 1f50576

Please sign in to comment.