@@ -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