Skip to content

Commit 314985e

Browse files
authored
fix: propagate drill down parent filters (#1143)
* fix: propagate drill down parent filters * drill down tests
1 parent ed1208d commit 314985e

File tree

3 files changed

+189
-6
lines changed

3 files changed

+189
-6
lines changed

packages/cubejs-api-gateway/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,10 @@ const normalizeQuery = (query) => {
294294
timezone,
295295
order: normalizeQueryOrder(query.order),
296296
filters: (query.filters || []).map(f => {
297+
const { dimension, member, ...filter } = f;
297298
const normalizedFlter = {
298-
...f,
299-
member: (f.dimension || f.member)
299+
...filter,
300+
member: member || dimension
300301
};
301302

302303
Object.defineProperty(normalizedFlter, "dimension", {

packages/cubejs-client-core/src/ResultSet.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class ResultSet {
103103
normalizedPivotConfig.x.forEach((member, currentIndex) => values.push([member, xValues[currentIndex]]));
104104
normalizedPivotConfig.y.forEach((member, currentIndex) => values.push([member, yValues[currentIndex]]));
105105

106+
const { filters: parentFilters = [] } = this.query();
106107
const { measures } = this.loadResponses[0].annotation;
107108
let [, measureName] = values.find(([member]) => member === 'measures') || [];
108109

@@ -114,10 +115,13 @@ class ResultSet {
114115
return null;
115116
}
116117

117-
const filters = [{
118-
member: measureName,
119-
operator: 'measureFilter',
120-
}];
118+
const filters = [
119+
{
120+
member: measureName,
121+
operator: 'measureFilter',
122+
},
123+
...parentFilters
124+
];
121125
const timeDimensions = [];
122126

123127
values.filter(([member]) => member !== 'measures')
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import 'jest';
2+
import ResultSet from '../ResultSet';
3+
4+
jest.mock('moment-range', () => {
5+
const Moment = jest.requireActual('moment');
6+
const MomentRange = jest.requireActual('moment-range');
7+
const moment = MomentRange.extendMoment(Moment);
8+
return {
9+
extendMoment: () => moment,
10+
};
11+
});
12+
13+
const loadResponse = (query = {}) => ({
14+
queryType: 'regularQuery',
15+
results: [
16+
{
17+
query: {
18+
measures: ['Orders.count'],
19+
timeDimensions: [
20+
{
21+
dimension: 'Orders.ts',
22+
granularity: 'day',
23+
dateRange: ['2020-08-01T00:00:00.000', '2020-08-07T23:59:59.999'],
24+
},
25+
],
26+
filters: [],
27+
timezone: 'UTC',
28+
order: [],
29+
dimensions: [],
30+
...query,
31+
},
32+
data: [
33+
{
34+
'Orders.ts.day': '2020-08-01T00:00:00.000',
35+
'Orders.ts': '2020-08-01T00:00:00.000',
36+
'Orders.count': 1,
37+
},
38+
{
39+
'Orders.ts.day': '2020-08-02T00:00:00.000',
40+
'Orders.ts': '2020-08-02T00:00:00.000',
41+
'Orders.count': 2,
42+
},
43+
],
44+
annotation: {
45+
measures: {
46+
'Orders.count': {
47+
title: 'Orders Count',
48+
shortTitle: 'Count',
49+
type: 'number',
50+
drillMembers: ['Orders.id', 'Orders.title'],
51+
drillMembersGrouped: {
52+
measures: [],
53+
dimensions: ['Orders.id', 'Orders.title'],
54+
},
55+
},
56+
},
57+
dimensions: {},
58+
segments: {},
59+
timeDimensions: {
60+
'Orders.ts.day': { title: 'Orders Ts', shortTitle: 'Ts', type: 'time' },
61+
'Orders.ts': { title: 'Orders Ts', shortTitle: 'Ts', type: 'time' },
62+
},
63+
},
64+
},
65+
],
66+
pivotQuery: {
67+
measures: ['Orders.count'],
68+
timeDimensions: [
69+
{
70+
dimension: 'Orders.ts',
71+
granularity: 'day',
72+
dateRange: ['2020-08-01T00:00:00.000', '2020-08-07T23:59:59.999'],
73+
},
74+
],
75+
filters: [],
76+
timezone: 'UTC',
77+
order: [],
78+
dimensions: [],
79+
...query,
80+
},
81+
});
82+
83+
describe('drill down query', () => {
84+
const resultSet1 = new ResultSet(loadResponse());
85+
const resultSet2 = new ResultSet(
86+
loadResponse({
87+
timezone: 'America/Los_Angeles',
88+
})
89+
);
90+
const resultSet3 = new ResultSet(
91+
loadResponse({
92+
filters: [
93+
{
94+
member: 'Users.country',
95+
operator: 'equals',
96+
values: ['Los Angeles'],
97+
},
98+
],
99+
})
100+
);
101+
102+
it('handles a query with a time dimension', () => {
103+
expect(
104+
resultSet1.drillDown({
105+
xValues: ['2020-08-01T00:00:00.000'],
106+
})
107+
).toEqual({
108+
measures: [],
109+
dimensions: ['Orders.id', 'Orders.title'],
110+
filters: [
111+
{
112+
member: 'Orders.count',
113+
operator: 'measureFilter',
114+
},
115+
],
116+
timeDimensions: [
117+
{
118+
dimension: 'Orders.ts',
119+
dateRange: ['2020-08-01T00:00:00.000', '2020-08-01T23:59:59.999'],
120+
},
121+
],
122+
timezone: 'UTC',
123+
});
124+
});
125+
126+
it('respects the time zone', () => {
127+
expect(
128+
resultSet2.drillDown({
129+
xValues: ['2020-08-01T00:00:00.000'],
130+
})
131+
).toEqual({
132+
measures: [],
133+
dimensions: ['Orders.id', 'Orders.title'],
134+
filters: [
135+
{
136+
member: 'Orders.count',
137+
operator: 'measureFilter',
138+
},
139+
],
140+
timeDimensions: [
141+
{
142+
dimension: 'Orders.ts',
143+
dateRange: ['2020-08-01T00:00:00.000', '2020-08-01T23:59:59.999'],
144+
},
145+
],
146+
timezone: 'America/Los_Angeles',
147+
});
148+
});
149+
150+
it('propagates parent filters', () => {
151+
expect(
152+
resultSet3.drillDown({
153+
xValues: ['2020-08-01T00:00:00.000'],
154+
})
155+
).toEqual({
156+
measures: [],
157+
dimensions: ['Orders.id', 'Orders.title'],
158+
filters: [
159+
{
160+
member: 'Orders.count',
161+
operator: 'measureFilter',
162+
},
163+
{
164+
member: 'Users.country',
165+
operator: 'equals',
166+
values: ['Los Angeles'],
167+
},
168+
],
169+
timeDimensions: [
170+
{
171+
dimension: 'Orders.ts',
172+
dateRange: ['2020-08-01T00:00:00.000', '2020-08-01T23:59:59.999'],
173+
},
174+
],
175+
timezone: 'UTC',
176+
});
177+
});
178+
});

0 commit comments

Comments
 (0)