Skip to content

Commit 7d8b07f

Browse files
feat(filters): added support for set and not set in where clause (#76)
* added support for set and not set in where clause * bumped package json * type fix * test update * bumped node and browser
1 parent 02a79ad commit 7d8b07f

File tree

11 files changed

+314
-10
lines changed

11 files changed

+314
-10
lines changed

meerkat-browser/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devrev/meerkat-browser",
3-
"version": "0.0.71",
3+
"version": "0.0.72",
44
"dependencies": {
55
"@swc/helpers": "~0.5.0",
66
"@devrev/meerkat-core": "*",

meerkat-core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devrev/meerkat-core",
3-
"version": "0.0.73",
3+
"version": "0.0.74",
44
"dependencies": {
55
"@swc/helpers": "~0.5.0"
66
},

meerkat-core/src/cube-filter-transformer/factory.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ import { lteTransform } from './lte/lte';
2525
import { notInDataRangeTransform } from './not-In-date-range/not-In-date-range';
2626
import { notContainsTransform } from './not-contains/not-contains';
2727
import { notEqualsTransform } from './not-equals/not-equals';
28+
import { notSetTransform } from './not-set/not-set';
2829
import { orDuckdbCondition } from './or/or';
30+
import { setTransform } from './set/set';
2931

3032
export type CubeToParseExpressionTransform = (
3133
query: QueryOperatorsWithInfo
@@ -54,6 +56,12 @@ const cubeFilterOperatorsToDuckdb = (cubeFilter: QueryOperatorsWithInfo) => {
5456
return inDataRangeTransform(cubeFilter);
5557
case 'notInDateRange':
5658
return notInDataRangeTransform(cubeFilter);
59+
case 'notSet': {
60+
return notSetTransform(cubeFilter);
61+
}
62+
case 'set': {
63+
return setTransform(cubeFilter);
64+
}
5765
default:
5866
throw new Error('Could not transform the filter');
5967
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { notSetTransform } from "./not-set";
2+
3+
describe("notSetTransform", () => {
4+
it("should return the correct expression for a given query", () => {
5+
const query = {
6+
member: "table.column"
7+
};
8+
9+
const expectedExpression = {
10+
class: "OPERATOR",
11+
type: "OPERATOR_IS_NULL",
12+
alias: "",
13+
children: [
14+
{
15+
class: "COLUMN_REF",
16+
type: "COLUMN_REF",
17+
alias: "",
18+
column_names: ["table", "column"]
19+
}
20+
]
21+
};
22+
23+
const result = notSetTransform(query);
24+
25+
expect(result).toEqual(expectedExpression);
26+
});
27+
it("should return the correct expression for a __ delimited query", () => {
28+
const query = {
29+
member: "table__column"
30+
};
31+
32+
const expectedExpression = {
33+
class: "OPERATOR",
34+
type: "OPERATOR_IS_NULL",
35+
alias: "",
36+
children: [
37+
{
38+
class: "COLUMN_REF",
39+
type: "COLUMN_REF",
40+
alias: "",
41+
column_names: ["table__column"]
42+
}
43+
]
44+
};
45+
46+
const result = notSetTransform(query);
47+
48+
expect(result).toEqual(expectedExpression);
49+
});
50+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { ExpressionClass, ExpressionType } from '../../types/duckdb-serialization-types/serialization/Expression';
2+
import { CubeToParseExpressionTransform } from "../factory";
3+
4+
export const notSetTransform: CubeToParseExpressionTransform = (query) => {
5+
const { member } = query;
6+
return {
7+
class: ExpressionClass.OPERATOR,
8+
type: ExpressionType.OPERATOR_IS_NULL,
9+
alias: "",
10+
children: [
11+
{
12+
class: "COLUMN_REF",
13+
type: "COLUMN_REF",
14+
alias: "",
15+
column_names: member.split('.')
16+
}
17+
]
18+
}
19+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { setTransform } from './set';
2+
3+
describe('setTransform', () => {
4+
it('should return the correct expression object', () => {
5+
const query = {
6+
member: 'table.column'
7+
};
8+
9+
const expected = {
10+
class: 'OPERATOR',
11+
type: 'OPERATOR_IS_NOT_NULL',
12+
alias: '',
13+
children: [
14+
{
15+
class: 'COLUMN_REF',
16+
type: 'COLUMN_REF',
17+
alias: '',
18+
column_names: ['table', 'column']
19+
}
20+
]
21+
};
22+
23+
const result = setTransform(query);
24+
25+
expect(result).toEqual(expected);
26+
});
27+
28+
it('should handle __ delimited query', () => {
29+
const query = {
30+
member: 'table__column'
31+
};
32+
33+
const expected = {
34+
class: 'OPERATOR',
35+
type: 'OPERATOR_IS_NOT_NULL',
36+
alias: '',
37+
children: [
38+
{
39+
class: 'COLUMN_REF',
40+
type: 'COLUMN_REF',
41+
alias: '',
42+
column_names: ['table__column']
43+
}
44+
]
45+
};
46+
47+
const result = setTransform(query);
48+
49+
expect(result).toEqual(expected);
50+
});
51+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { ExpressionClass, ExpressionType } from '../../types/duckdb-serialization-types/serialization/Expression';
2+
import { CubeToParseExpressionTransform } from "../factory";
3+
4+
export const setTransform: CubeToParseExpressionTransform = (query) => {
5+
const { member } = query;
6+
return {
7+
class: ExpressionClass.OPERATOR,
8+
type: ExpressionType.OPERATOR_IS_NOT_NULL,
9+
alias: "",
10+
children: [
11+
{
12+
class: "COLUMN_REF",
13+
type: "COLUMN_REF",
14+
alias: "",
15+
column_names: member.split('.')
16+
}
17+
]
18+
}
19+
}

meerkat-core/src/utils/key-from-measures-dimension.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ export const getMemberInfoFromTableSchema = (
77
let memberInfo: Measure | Dimension | undefined;
88

99
const memberKeyName = memberKey.split('.')[1];
10-
console.info('memberKeyName', memberKeyName, memberKey);
1110

1211
/**
1312
* Finding the table key from the measures.

meerkat-node/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devrev/meerkat-node",
3-
"version": "0.0.71",
3+
"version": "0.0.72",
44
"dependencies": {
55
"@swc/helpers": "~0.5.0",
66
"@devrev/meerkat-core": "*",

meerkat-node/src/__tests__/cube-filter-params.spec.ts

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ describe('filter-param-tests', () => {
4242
(4, DATE '2022-03-01', 'cancelled', 40.00),
4343
(5, DATE '2022-01-28', 'completed', 80.75),
4444
(6, DATE '2022-02-15', 'pending', 120.00),
45-
(7, DATE '2022-04-01', 'completed', 210.00);`);
45+
(7, DATE '2022-02-15', 'pending', 120.00),
46+
(8, DATE '2022-04-01', 'initiated', null);`);
4647
});
4748

4849
it('Should apply filter params to base SQL', async () => {
@@ -60,7 +61,7 @@ describe('filter-param-tests', () => {
6061
const sql = await cubeQueryToSQL(query, [SCHEMA]);
6162
console.info('SQL: ', sql);
6263
const output: any = await duckdbExec(sql);
63-
expect(output).toHaveLength(1);
64+
expect(output).toHaveLength(2);
6465
expect(output[0].id).toBe(6);
6566
});
6667

@@ -93,7 +94,7 @@ describe('filter-param-tests', () => {
9394
const sql = await cubeQueryToSQL(query, [SCHEMA]);
9495
console.info('SQL: ', sql);
9596
const output: any = await duckdbExec(sql);
96-
expect(output).toHaveLength(2);
97+
expect(output).toHaveLength(3);
9798
expect(output[0].id).toBe(6);
9899
});
99100

@@ -107,7 +108,7 @@ describe('filter-param-tests', () => {
107108
const sql = await cubeQueryToSQL(query, [SCHEMA]);
108109
console.info('SQL: ', sql);
109110
const output: any = await duckdbExec(sql);
110-
expect(output).toHaveLength(7);
111+
expect(output).toHaveLength(8);
111112
});
112113

113114
it('Should apply true filter if filters are present but are not matching', async () => {
@@ -139,6 +140,31 @@ describe('filter-param-tests', () => {
139140
const sql = await cubeQueryToSQL(query, [SCHEMA]);
140141
console.info('SQL: ', sql);
141142
const output: any = await duckdbExec(sql);
142-
expect(output).toHaveLength(4);
143+
expect(output).toHaveLength(5);
144+
});
145+
it('Should apply notSet and set filters', async () => {
146+
const query = {
147+
measures: ['*'],
148+
filters: [
149+
{
150+
and: [
151+
{
152+
member: 'orders.amount',
153+
operator: 'notSet',
154+
},
155+
{
156+
member: 'orders.status',
157+
operator: 'set',
158+
}
159+
],
160+
},
161+
],
162+
dimensions: [],
163+
};
164+
165+
const sql = await cubeQueryToSQL(query, [SCHEMA]);
166+
console.info('SQL: ', sql);
167+
const output: any = await duckdbExec(sql);
168+
expect(output).toHaveLength(1);
143169
});
144170
});

0 commit comments

Comments
 (0)