Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/cubejs-schema-compiler/src/compiler/CubeSymbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,8 @@ export class CubeSymbols {
...(resolvedMember.multiStage && { multiStage: resolvedMember.multiStage }),
...(resolvedMember.timeShift && { timeShift: resolvedMember.timeShift }),
...(resolvedMember.orderBy && { orderBy: resolvedMember.orderBy }),
...(resolvedMember.drillMembers && { drillMembers: resolvedMember.drillMembers }),
...(resolvedMember.drillMembersGrouped && { drillMembersGrouped: resolvedMember.drillMembersGrouped }),
};
} else if (type === 'dimensions') {
memberDefinition = {
Expand Down Expand Up @@ -891,8 +893,7 @@ export class CubeSymbols {
name
);
// eslint-disable-next-line no-underscore-dangle
// if (resolvedSymbol && resolvedSymbol._objectWithResolvedProperties) {
if (resolvedSymbol._objectWithResolvedProperties) {
if (resolvedSymbol && resolvedSymbol._objectWithResolvedProperties) {
return resolvedSymbol;
}
return cubeEvaluator.pathFromArray(fullPath(cubeEvaluator.joinHints(), [referencedCube, name]));
Expand Down Expand Up @@ -1002,7 +1003,7 @@ export class CubeSymbols {
cubeName,
name
);
if (resolvedSymbol._objectWithResolvedProperties) {
if (resolvedSymbol && resolvedSymbol._objectWithResolvedProperties) {
return resolvedSymbol;
}
return '';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,32 @@ export class CubeToMetaTransformer {
cubeName, drillMembers, { originalSorting: true }
)) || [];

// Filter drill members for views to only include available members
if (drillMembersArray.length > 0) {
const cubeSymbol = this.cubeEvaluator.symbols[cubeName];
if (cubeSymbol) {
const cube = cubeSymbol.cubeObj();
if (cube && cube.isView) {
const availableMembers = new Set();
// Collect all available member names from all types
['measures', 'dimensions', 'segments'].forEach(memberType => {
if (cube[memberType]) {
Object.keys(cube[memberType]).forEach(memberName => {
availableMembers.add(`${cubeName}.${memberName}`);
});
}
});

// Filter drill members to only include those available in the view
const filteredDrillMembers = drillMembersArray.filter(member => availableMembers.has(member));

// Update the drillMembersArray with filtered results
drillMembersArray.length = 0;
drillMembersArray.push(...filteredDrillMembers);
}
}
}

const type = CubeSymbols.toMemberDataType(nameToMetric[1].type);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class ErrorReporter {
if (this.rootReporter().errors.length) {
throw new CompileError(
this.rootReporter().errors.map((e) => e.message).join('\n'),
this.rootReporter().errors.map((e) => e.plainMessage).join('\n')
this.rootReporter().errors.map((e) => e.plainMessage || e.message || '').join('\n')
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ cube(\`Orders\`, {
measures: {
count: {
type: \`count\`,
//drillMembers: [id, createdAt]
drillMembers: [id, createdAt]
},

runningTotal: {
Expand Down Expand Up @@ -255,6 +255,13 @@ view(\`OrdersView3\`, {
split: true
}]
});

view(\`OrdersSimpleView\`, {
cubes: [{
join_path: Orders,
includes: ['createdAt', 'count']
}]
});
Comment on lines +258 to +264
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The important part is that id is a drill member for count, but it is not included.

`);

async function runQueryTest(q: any, expectedResult: any, additionalTest?: (query: BaseQuery) => any) {
Expand Down Expand Up @@ -429,4 +436,73 @@ view(\`OrdersView3\`, {
orders_view3__count: '2',
orders_view3__product_categories__name: 'Groceries',
}]));

it('check drillMembers are inherited in views', async () => {
await compiler.compile();
const cube = metaTransformer.cubes.find(c => c.config.name === 'OrdersView');
const countMeasure = cube.config.measures.find((m) => m.name === 'OrdersView.count');
expect(countMeasure.drillMembers).toEqual(['OrdersView.id', 'OrdersView.createdAt']);
expect(countMeasure.drillMembersGrouped).toEqual({
measures: [],
dimensions: ['OrdersView.id', 'OrdersView.createdAt']
});
});

it('verify drill member inheritance functionality', async () => {
await compiler.compile();

// Check that the source Orders cube has drill members
const sourceOrdersCube = metaTransformer.cubes.find(c => c.config.name === 'Orders');
const sourceCountMeasure = sourceOrdersCube.config.measures.find((m) => m.name === 'Orders.count');
expect(sourceCountMeasure.drillMembers).toEqual(['Orders.id', 'Orders.createdAt']);

// Check that the OrdersView cube inherits these drill members with correct naming
const viewCube = metaTransformer.cubes.find(c => c.config.name === 'OrdersView');
const viewCountMeasure = viewCube.config.measures.find((m) => m.name === 'OrdersView.count');

// Before our fix, this would have been undefined or empty
// After our fix, drill members are properly inherited and renamed to use the view naming
expect(viewCountMeasure.drillMembers).toBeDefined();
expect(Array.isArray(viewCountMeasure.drillMembers)).toBe(true);
expect(viewCountMeasure.drillMembers.length).toBeGreaterThan(0);
expect(viewCountMeasure.drillMembers).toContain('OrdersView.id');
expect(viewCountMeasure.drillMembersGrouped).toBeDefined();
});

it('check drill member inheritance with limited includes in OrdersSimpleView', async () => {
await compiler.compile();
const cube = metaTransformer.cubes.find(c => c.config.name === 'OrdersSimpleView');

if (!cube) {
throw new Error('OrdersSimpleView not found in compiled cubes');
}

const countMeasure = cube.config.measures.find((m) => m.name === 'OrdersSimpleView.count');

if (!countMeasure) {
throw new Error('OrdersSimpleView.count measure not found');
}

// Check what dimensions are actually available in this limited view
const availableDimensions = cube.config.dimensions?.map(d => d.name) || [];
console.log('OrdersSimpleView dimensions:', availableDimensions);
console.log('OrdersSimpleView drill members:', countMeasure.drillMembers);

// This view only includes ['id', 'createdAt', 'count'] - should have both id and createdAt
expect(availableDimensions).not.toContain('OrdersSimpleView.id');
expect(availableDimensions).toContain('OrdersSimpleView.createdAt');

// The source measure has drillMembers: ['Orders.id', 'Orders.createdAt']
// Both should be available in this view since we explicitly included them
expect(countMeasure.drillMembers).toBeDefined();
expect(Array.isArray(countMeasure.drillMembers)).toBe(true);
expect(countMeasure.drillMembers.length).toBeGreaterThan(0);

// Verify drill members are inherited and correctly transformed to use View naming
expect(countMeasure.drillMembers).toEqual(['OrdersSimpleView.createdAt']);
expect(countMeasure.drillMembersGrouped).toEqual({
measures: [],
dimensions: ['OrdersSimpleView.createdAt']
});
});
Comment on lines +500 to +505
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where we test that id is not in the drill members.

});
Loading