@@ -243,10 +243,39 @@ export class CubeSymbols {
243243 allMembers : new Set ( ) ,
244244 } ;
245245
246- const types = [ 'measures' , 'dimensions' , 'segments' , 'hierarchies' ] ;
246+ const autoIncludeMembers = new Set ( ) ;
247+ // `hierarchies` must be processed first
248+ const types = [ 'hierarchies' , 'measures' , 'dimensions' , 'segments' ] ;
249+
247250 for ( const type of types ) {
248- const cubeIncludes = cube . cubes && this . membersFromCubes ( cube , cube . cubes , type , errorReporter , splitViews , memberSets ) || [ ] ;
251+ let cubeIncludes = [ ] ;
252+ if ( cube . cubes ) {
253+ // If the hierarchy is included all members from it should be included as well
254+ // Extend `includes` with members from hierarchies that should be auto-included
255+ const cubes = type === 'dimensions' ? cube . cubes . map ( ( it ) => {
256+ const fullPath = this . evaluateReferences ( null , it . joinPath , { collectJoinHints : true } ) ;
257+ const split = fullPath . split ( '.' ) ;
258+ const cubeRef = split [ split . length - 1 ] ;
259+
260+ if ( it . includes === '*' ) {
261+ return it ;
262+ }
263+
264+ const currentCubeAutoIncludeMembers = Array . from ( autoIncludeMembers )
265+ . filter ( ( path ) => path . startsWith ( `${ cubeRef } .` ) )
266+ . map ( ( path ) => path . split ( '.' ) [ 1 ] )
267+ . filter ( memberName => ! it . includes . find ( ( include ) => ( include . name || include ) === memberName ) ) ;
249268
269+ return {
270+ ...it ,
271+ includes : ( it . includes || [ ] ) . concat ( currentCubeAutoIncludeMembers ) ,
272+ } ;
273+ } ) : cube . cubes ;
274+
275+ cubeIncludes = this . membersFromCubes ( cube , cubes , type , errorReporter , splitViews , memberSets ) || [ ] ;
276+ }
277+
278+ // This is the deprecated approach
250279 const includes = cube . includes && this . membersFromIncludeExclude ( cube . includes , cube . name , type ) || [ ] ;
251280 const excludes = cube . excludes && this . membersFromIncludeExclude ( cube . excludes , cube . name , type ) || [ ] ;
252281
@@ -256,6 +285,21 @@ export class CubeSymbols {
256285 excludes
257286 ) ;
258287
288+ if ( type === 'hierarchies' ) {
289+ for ( const member of finalIncludes ) {
290+ const path = member . member . split ( '.' ) ;
291+ const cubeName = path [ path . length - 2 ] ;
292+ const hierarchyName = path [ path . length - 1 ] ;
293+ const hierarchy = this . getResolvedMember ( type , cubeName , hierarchyName ) ;
294+
295+ if ( hierarchy ) {
296+ const levels = this . evaluateReferences ( cubeName , this . getResolvedMember ( 'hierarchies' , cubeName , hierarchyName ) . levels , { originalSorting : true } ) ;
297+
298+ levels . forEach ( ( level ) => autoIncludeMembers . add ( level ) ) ;
299+ }
300+ }
301+ }
302+
259303 const includeMembers = this . generateIncludeMembers ( finalIncludes , cube . name , type ) ;
260304 this . applyIncludeMembers ( includeMembers , cube , type , errorReporter ) ;
261305
@@ -278,7 +322,7 @@ export class CubeSymbols {
278322 applyIncludeMembers ( includeMembers , cube , type , errorReporter ) {
279323 for ( const [ memberName , memberDefinition ] of includeMembers ) {
280324 if ( cube [ type ] ?. [ memberName ] ) {
281- errorReporter . error ( `Included member '${ memberName } ' conflicts with existing member of '${ cube . name } '. Please consider excluding this member.` ) ;
325+ errorReporter . error ( `Included member '${ memberName } ' conflicts with existing member of '${ cube . name } '. Please consider excluding this member or assigning it an alias .` ) ;
282326 } else if ( type !== 'hierarchies' ) {
283327 cube [ type ] [ memberName ] = memberDefinition ;
284328 }
@@ -300,11 +344,7 @@ export class CubeSymbols {
300344
301345 if ( cubeInclude . includes === '*' ) {
302346 const membersObj = this . symbols [ cubeReference ] ?. cubeObj ( ) ?. [ type ] || { } ;
303- if ( Array . isArray ( membersObj ) ) {
304- includes = membersObj . map ( it => ( { member : `${ fullPath } .${ it . name } ` , name : fullMemberName ( it . name ) } ) ) ;
305- } else {
306- includes = Object . keys ( membersObj ) . map ( memberName => ( { member : `${ fullPath } .${ memberName } ` , name : fullMemberName ( memberName ) } ) ) ;
307- }
347+ includes = Object . keys ( membersObj ) . map ( memberName => ( { member : `${ fullPath } .${ memberName } ` , name : fullMemberName ( memberName ) } ) ) ;
308348 } else {
309349 includes = cubeInclude . includes . map ( include => {
310350 const member = include . alias || include ;
@@ -397,10 +437,6 @@ export class CubeSymbols {
397437 * @protected
398438 */
399439 getResolvedMember ( type , cubeName , memberName ) {
400- if ( Array . isArray ( this . symbols [ cubeName ] ?. cubeObj ( ) ?. [ type ] ) ) {
401- return this . symbols [ cubeName ] ?. cubeObj ( ) ?. [ type ] ?. find ( ( it ) => it . name === memberName ) ;
402- }
403-
404440 return this . symbols [ cubeName ] ?. cubeObj ( ) ?. [ type ] ?. [ memberName ] ;
405441 }
406442
0 commit comments