Skip to content

Commit 5da5e61

Browse files
authored
fix(client-core): drill down check the parent date range bounds (#6639)
1 parent b7e47fa commit 5da5e61

File tree

2 files changed

+199
-32
lines changed

2 files changed

+199
-32
lines changed

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

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class ResultSet {
127127
throw new Error('Data blending drillDown query is not currently supported');
128128
}
129129

130+
const { query } = this.loadResponses[0];
130131
const { xValues = [], yValues = [] } = drillDownLocator;
131132
const normalizedPivotConfig = this.normalizePivotConfig(pivotConfig);
132133

@@ -161,13 +162,25 @@ class ResultSet {
161162

162163
if (granularity !== undefined) {
163164
const range = dayRange(value, value).snapTo(granularity);
165+
const originalTimeDimension = query.timeDimensions.find((td) => td.dimension);
166+
167+
let dateRange = [
168+
range.start,
169+
range.end
170+
];
171+
172+
if (originalTimeDimension) {
173+
const [originalStart, originalEnd] = originalTimeDimension.dateRange;
174+
175+
dateRange = [
176+
dayjs(originalStart) > range.start ? dayjs(originalStart) : range.start,
177+
dayjs(originalEnd) < range.end ? dayjs(originalEnd) : range.end,
178+
];
179+
}
164180

165181
timeDimensions.push({
166182
dimension: [cubeName, dimension].join('.'),
167-
dateRange: [
168-
range.start,
169-
range.end
170-
].map((dt) => dt.format('YYYY-MM-DDTHH:mm:ss.SSS')),
183+
dateRange: dateRange.map((dt) => dt.format('YYYY-MM-DDTHH:mm:ss.SSS')),
171184
});
172185
} else if (value == null) {
173186
filters.push({
@@ -182,8 +195,7 @@ class ResultSet {
182195
});
183196
}
184197
});
185-
186-
const { query } = this.loadResponses[0];
198+
187199
if (
188200
timeDimensions.length === 0 &&
189201
query.timeDimensions.length > 0 &&

packages/cubejs-client-core/src/tests/drill-down.test.js

Lines changed: 181 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ const loadResponse = (query = {}) => ({
5757
dimensions: {},
5858
segments: {},
5959
timeDimensions: {
60-
'Orders.ts.day': { title: 'Orders Ts', shortTitle: 'Ts', type: 'time' },
60+
'Orders.ts.day': {
61+
title: 'Orders Ts',
62+
shortTitle: 'Ts',
63+
type: 'time',
64+
},
6165
'Orders.ts': { title: 'Orders Ts', shortTitle: 'Ts', type: 'time' },
6266
},
6367
},
@@ -80,6 +84,139 @@ const loadResponse = (query = {}) => ({
8084
},
8185
});
8286

87+
const loadResponse2 = {
88+
queryType: 'regularQuery',
89+
results: [
90+
{
91+
query: {
92+
measures: ['Orders.count'],
93+
timeDimensions: [
94+
{
95+
dimension: 'Orders.createdAt',
96+
granularity: 'week',
97+
dateRange: ['2023-05-10T00:00:00.000', '2023-05-14T23:59:59.999'],
98+
},
99+
],
100+
limit: 10000,
101+
timezone: 'UTC',
102+
order: [],
103+
filters: [],
104+
dimensions: [],
105+
rowLimit: 10000,
106+
queryType: 'regularQuery',
107+
},
108+
data: [
109+
{
110+
'Orders.createdAt.week': '2023-05-08T00:00:00.000',
111+
'Orders.createdAt': '2023-05-08T00:00:00.000',
112+
'Orders.count': '21',
113+
},
114+
],
115+
lastRefreshTime: '2023-05-22T14:46:45.000Z',
116+
usedPreAggregations: {
117+
'prod_pre_aggregations.orders_main': {
118+
targetTableName:
119+
'prod_pre_aggregations.orders_main20230508_instgodu_ehgypjtt_1i6n02l',
120+
refreshKeyValues: [[]],
121+
lastUpdatedAt: 1684766805000,
122+
},
123+
},
124+
transformedQuery: {
125+
sortedDimensions: [],
126+
sortedTimeDimensions: [['Orders.createdAt', 'day']],
127+
timeDimensions: [['Orders.createdAt', 'week']],
128+
measures: ['Orders.count'],
129+
leafMeasureAdditive: true,
130+
leafMeasures: ['Orders.count'],
131+
measureToLeafMeasures: {
132+
'Orders.count': [
133+
{ measure: 'Orders.count', additive: true, type: 'count' },
134+
],
135+
},
136+
hasNoTimeDimensionsWithoutGranularity: true,
137+
allFiltersWithinSelectedDimensions: true,
138+
isAdditive: true,
139+
granularityHierarchies: {
140+
year: [
141+
'year',
142+
'quarter',
143+
'month',
144+
'month',
145+
'day',
146+
'hour',
147+
'minute',
148+
'second',
149+
],
150+
quarter: ['quarter', 'month', 'day', 'hour', 'minute', 'second'],
151+
month: ['month', 'day', 'hour', 'minute', 'second'],
152+
week: ['week', 'day', 'hour', 'minute', 'second'],
153+
day: ['day', 'hour', 'minute', 'second'],
154+
hour: ['hour', 'minute', 'second'],
155+
minute: ['minute', 'second'],
156+
second: ['second'],
157+
},
158+
hasMultipliedMeasures: false,
159+
hasCumulativeMeasures: false,
160+
windowGranularity: null,
161+
filterDimensionsSingleValueEqual: {},
162+
ownedDimensions: [],
163+
ownedTimeDimensionsWithRollupGranularity: [['Orders.createdAt', 'day']],
164+
ownedTimeDimensionsAsIs: [['Orders.createdAt', 'week']],
165+
},
166+
requestId: 'x',
167+
annotation: {
168+
measures: {
169+
'Orders.count': {
170+
title: 'Orders Count',
171+
shortTitle: 'Count',
172+
type: 'number',
173+
drillMembers: ['Orders.id', 'Orders.createdAt'],
174+
drillMembersGrouped: {
175+
measures: [],
176+
dimensions: ['Orders.id', 'Orders.createdAt'],
177+
},
178+
},
179+
},
180+
dimensions: {},
181+
segments: {},
182+
timeDimensions: {
183+
'Orders.createdAt.week': {
184+
title: 'Orders Created at',
185+
shortTitle: 'Created at',
186+
type: 'time',
187+
},
188+
'Orders.createdAt': {
189+
title: 'Orders Created at',
190+
shortTitle: 'Created at',
191+
type: 'time',
192+
},
193+
},
194+
},
195+
dataSource: 'default',
196+
dbType: 'postgres',
197+
extDbType: 'cubestore',
198+
},
199+
],
200+
pivotQuery: {
201+
measures: ['Orders.count'],
202+
timeDimensions: [
203+
{
204+
dimension: 'Orders.createdAt',
205+
granularity: 'week',
206+
dateRange: ['2023-05-10T00:00:00.000', '2023-05-14T23:59:59.999'],
207+
},
208+
],
209+
limit: 10000,
210+
timezone: 'UTC',
211+
order: [],
212+
filters: [],
213+
dimensions: [],
214+
rowLimit: 10000,
215+
queryType: 'regularQuery',
216+
},
217+
slowQuery: false,
218+
};
219+
83220
describe('drill down query', () => {
84221
const resultSet1 = new ResultSet(loadResponse());
85222
const resultSet2 = new ResultSet(
@@ -101,7 +238,7 @@ describe('drill down query', () => {
101238
const resultSet4 = new ResultSet(
102239
loadResponse({
103240
dimensions: ['Statuses.potential'],
104-
timeDimensions: []
241+
timeDimensions: [],
105242
})
106243
);
107244

@@ -184,31 +321,49 @@ describe('drill down query', () => {
184321
timezone: 'UTC',
185322
});
186323
});
187-
324+
188325
it('handles null values', () => {
326+
expect(resultSet4.drillDown({ xvalues: [null] })).toEqual({
327+
measures: [],
328+
segments: [],
329+
dimensions: ['Orders.id', 'Orders.title'],
330+
filters: [
331+
{
332+
member: 'Orders.count',
333+
operator: 'measureFilter',
334+
},
335+
{
336+
member: 'Statuses.potential',
337+
operator: 'notSet',
338+
},
339+
],
340+
timeDimensions: [],
341+
timezone: 'UTC',
342+
});
343+
});
344+
345+
it('respects the parent time dimension date range', () => {
346+
const resultSet = new ResultSet(loadResponse2);
347+
189348
expect(
190-
resultSet4.drillDown({ xvalues: [null] })
191-
).toEqual(
192-
{
193-
measures: [],
194-
segments: [],
195-
dimensions: [
196-
'Orders.id',
197-
'Orders.title',
198-
],
199-
filters: [
200-
{
201-
member: 'Orders.count',
202-
operator: 'measureFilter',
203-
},
204-
{
205-
member: 'Statuses.potential',
206-
operator: 'notSet',
207-
},
208-
],
209-
timeDimensions: [],
210-
timezone: 'UTC',
211-
}
212-
);
349+
resultSet.drillDown({ xValues: ['2023-05-08T00:00:00.000'] })
350+
).toEqual({
351+
measures: [],
352+
segments: [],
353+
dimensions: ['Orders.id', 'Orders.createdAt'],
354+
filters: [
355+
{
356+
operator: 'measureFilter',
357+
member: 'Orders.count',
358+
},
359+
],
360+
timeDimensions: [
361+
{
362+
dimension: 'Orders.createdAt',
363+
dateRange: ['2023-05-10T00:00:00.000', '2023-05-14T23:59:59.999'],
364+
},
365+
],
366+
timezone: 'UTC'
367+
});
213368
});
214369
});

0 commit comments

Comments
 (0)