Skip to content

Commit 39d024b

Browse files
committed
fix joint hints collection for transitive joins
1 parent 8ad21df commit 39d024b

File tree

1 file changed

+35
-3
lines changed

1 file changed

+35
-3
lines changed

packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,34 @@ export class BaseQuery {
505505
return joinMaps;
506506
}
507507

508+
/**
509+
* @private
510+
* @param { import('../compiler/JoinGraph').FinishedJoinTree } joinTree
511+
* @param { string[] } joinHints
512+
* @return { string[][] }
513+
*/
514+
enrichedJoinHintsFromJoinTree(joinTree, joinHints) {
515+
const joinsMap = {};
516+
517+
for (const j of joinTree.joins) {
518+
joinsMap[j.to] = j.from;
519+
}
520+
521+
return joinHints.map(jh => {
522+
let cubeName = jh;
523+
const path = [cubeName];
524+
while (joinsMap[cubeName]) {
525+
cubeName = joinsMap[cubeName];
526+
path.push(cubeName);
527+
}
528+
529+
if (path.length === 1) {
530+
return path[0];
531+
}
532+
return path.reverse();
533+
});
534+
}
535+
508536
/**
509537
* @private
510538
* @param { (string|string[])[] } hints
@@ -2669,7 +2697,7 @@ export class BaseQuery {
26692697
const explicitJoinHintMembers = new Set(allMembersJoinHints.filter(j => Array.isArray(j)).flat());
26702698
const queryJoinMaps = this.queryJoinMap();
26712699
const customSubQueryJoinHints = this.collectJoinHintsFromMembers(this.joinMembersFromCustomSubQuery());
2672-
const newCollectedHints = [];
2700+
let newCollectedHints = [];
26732701

26742702
// One cube may join the other cube via transitive joined cubes,
26752703
// members from which are referenced in the join `on` clauses.
@@ -2703,8 +2731,12 @@ export class BaseQuery {
27032731
const iterationCollectedHints = joinMembersJoinHints.filter(j => !allJoinHintsFlatten.has(j));
27042732
newJoinHintsCollectedCnt = iterationCollectedHints.length;
27052733
cnt++;
2706-
if (newJoin) {
2707-
newCollectedHints.push(...joinMembersJoinHints.filter(j => !explicitJoinHintMembers.has(j)));
2734+
if (newJoin && newJoin.joins.length > 0) {
2735+
// Even if there is no join tree changes, we still
2736+
// push correctly ordered join hints, collected from the resolving of members of join tree
2737+
// upfront the all existing query members. This ensures the correct cube join order
2738+
// with transitive joins even if they are already presented among query members.
2739+
newCollectedHints = this.enrichedJoinHintsFromJoinTree(newJoin, joinMembersJoinHints);
27082740
}
27092741
} while (newJoin?.joins.length > 0 && !this.isJoinTreesEqual(prevJoin, newJoin) && cnt < 10000 && newJoinHintsCollectedCnt > 0);
27102742

0 commit comments

Comments
 (0)