Skip to content

Commit

Permalink
fix multiple TDs request SQL generation
Browse files Browse the repository at this point in the history
  • Loading branch information
KSDaemon committed Jan 22, 2025
1 parent c379045 commit 92f6c78
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 14 deletions.
66 changes: 53 additions & 13 deletions packages/cubejs-schema-compiler/src/adapter/BaseQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -1413,18 +1413,59 @@ export class BaseQuery {

overTimeSeriesQuery(baseQueryFn, cumulativeMeasure, fromRollup) {
const dateJoinCondition = cumulativeMeasure.dateJoinCondition();
const uniqDateJoinCondition = R.uniqBy(djc => djc[0].dimension, dateJoinCondition);
const cumulativeMeasures = [cumulativeMeasure];
if (!this.timeDimensions.find(d => d.granularity)) {
const filters = this.segments.concat(this.filters).concat(this.dateFromStartToEndConditionSql(dateJoinCondition, fromRollup, false));
const filters = this.segments
.concat(this.filters)
.concat(this.dateFromStartToEndConditionSql(
// If the same time dimension is passed more than once, no need to build the same
// filter condition again and again. Different granularities don't play role here,
// as rollingWindow.granularity is used for filtering.
uniqDateJoinCondition,
fromRollup,
false
));
return baseQueryFn(cumulativeMeasures, filters, false);
}
const dateSeriesSql = this.timeDimensions.map(d => this.dateSeriesSql(d)).join(', ');
const filters = this.segments.concat(this.filters).concat(this.dateFromStartToEndConditionSql(dateJoinCondition, fromRollup, true));

// We can't do meaningful query if few time dimensions with different ranges passed,
// it won't be possible to join them together without loosing some rows.
const rangedTimeDimensions = this.timeDimensions.filter(d => d.dateRange && d.granularity);
const uniqTimeDimensionWithRanges = R.uniqBy(d => d.dateRange, rangedTimeDimensions);
if (uniqTimeDimensionWithRanges.length > 1) {
throw new Error('Can\'t build query for time dimensions with different date ranges');
}

// We need to generate time series table for the lowest granularity among all time dimensions
let dateSeriesDimension;
const dateSeriesGranularity = this.timeDimensions.filter(d => d.granularity)
.reduce((acc, d) => {
const mg = this.minGranularity(acc, d.resolvedGranularity());
if (mg === d.resolvedGranularity()) {
dateSeriesDimension = d;
}
return mg;
}, undefined);

const dateSeriesSql = this.dateSeriesSql(dateSeriesDimension);

// If the same time dimension is passed more than once, no need to build the same
// filter condition again and again. Different granularities don't play role here,
// as rollingWindow.granularity is used for filtering.
const filters = this.segments
.concat(this.filters)
.concat(this.dateFromStartToEndConditionSql(
uniqDateJoinCondition,
fromRollup,
true
));
const baseQuery = this.groupedUngroupedSelect(
() => baseQueryFn(cumulativeMeasures, filters),
cumulativeMeasure.shouldUngroupForCumulative(),
!cumulativeMeasure.shouldUngroupForCumulative() && this.minGranularity(
cumulativeMeasure.windowGranularity(), this.timeDimensions.find(d => d.granularity).resolvedGranularity()
cumulativeMeasure.windowGranularity(),
dateSeriesGranularity
) || undefined
);
const baseQueryAlias = this.cubeAlias('base');
Expand All @@ -1444,7 +1485,7 @@ export class BaseQuery {
dateSeriesSql,
baseQuery,
dateJoinConditionSql,
baseQueryAlias
baseQueryAlias,
);
}

Expand All @@ -1456,16 +1497,14 @@ export class BaseQuery {
}

overTimeSeriesForSelect(cumulativeMeasures) {
return this.dimensions.map(s => s.cumulativeSelectColumns()).concat(this.dateSeriesSelect()).concat(
cumulativeMeasures.map(s => s.cumulativeSelectColumns()),
).filter(c => !!c)
return this.dimensions
.map(s => s.cumulativeSelectColumns())
.concat(this.timeDimensions.map(d => d.dateSeriesSelectColumn()))
.concat(cumulativeMeasures.map(s => s.cumulativeSelectColumns()))
.filter(c => !!c)
.join(', ');
}

dateSeriesSelect() {
return this.timeDimensions.map(d => d.dateSeriesSelectColumn());
}

dateFromStartToEndConditionSql(dateJoinCondition, fromRollup, isFromStartToEnd) {
return dateJoinCondition.map(
// TODO these weird conversions to be strict typed for big query.
Expand Down Expand Up @@ -1646,7 +1685,8 @@ export class BaseQuery {

/**
*
* @param {{sql: string, on: {cubeName: string, expression: Function}, joinType: 'LEFT' | 'INNER', alias: string}} customJoin
* @param {{sql: string, on: {cubeName: string, expression: Function}, joinType: 'LEFT' | 'INNER', alias: string}}
* customJoin
* @returns {JoinItem}
*/
customSubQueryJoin(customJoin) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ export class BaseTimeDimension extends BaseFilter {
return this.query.escapeColumnName(`${this.dimension}_series`);
}

public dateSeriesSelectColumn(dateSeriesAliasName) {
public dateSeriesSelectColumn(dateSeriesAliasName: string) {
if (!this.granularityObj) {
return null;
}

return `${dateSeriesAliasName || this.dateSeriesAliasName()}.${this.query.escapeColumnName('date_from')} ${this.aliasName()}`;
}

Expand Down

0 comments on commit 92f6c78

Please sign in to comment.