Skip to content

Commit

Permalink
fix(schema-compiler): respect view prefix and member alias in hierarc… (
Browse files Browse the repository at this point in the history
  • Loading branch information
vasilev-alex committed May 6, 2024
1 parent 9468f90 commit 59fddea
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 26 deletions.
56 changes: 37 additions & 19 deletions packages/cubejs-schema-compiler/src/compiler/CubeEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,31 +116,49 @@ export class CubeEvaluator extends CubeSymbols {
}

private prepareHierarchies(cube: any) {
if (cube.isView && !cube.hierarchies && (cube.includedMembers || []).length) {
const includedCubeNames: string[] = R.uniq(cube.includedMembers.map(m => m.split('.')[0]));

for (const cubeName of includedCubeNames) {
const { hierarchies } = this.evaluatedCubes[cubeName];
if (Array.isArray(cube.hierarchies)) {
cube.hierarchies = cube.hierarchies.map(hierarchy => ({
...hierarchy,
levels: this.evaluateReferences(
cube.name, hierarchy.levels, { originalSorting: true }
)
}));
}

if (cube.isView && (cube.includedMembers || []).length) {
const includedCubeNames: string[] = R.uniq(cube.includedMembers.map(it => it.memberPath.split('.')[0]));
const includedMemberPaths: string[] = R.uniq(cube.includedMembers.map(it => it.memberPath));

if (!cube.hierarchies) {
for (const cubeName of includedCubeNames) {
const { hierarchies } = this.evaluatedCubes[cubeName] || {};

if (Array.isArray(hierarchies) && hierarchies.length) {
const filteredHierarchies = hierarchies.map(it => {
const levels = it.levels.filter(level => cube.includedMembers.includes(level));
if (Array.isArray(hierarchies) && hierarchies.length) {
const filteredHierarchies = hierarchies.map(it => {
const levels = it.levels.filter(level => includedMemberPaths.includes(level));

return {
...it,
levels
};
}).filter(it => it.levels.length);
return {
...it,
levels
};
}).filter(it => it.levels.length);

cube.hierarchies = [...(cube.hierarchies || []), ...filteredHierarchies];
cube.hierarchies = [...(cube.hierarchies || []), ...filteredHierarchies];
}
}
}
} else if (Array.isArray(cube.hierarchies)) {
cube.hierarchies = cube.hierarchies.map(hierarchy => ({

cube.hierarchies = (cube.hierarchies || []).map((hierarchy) => ({
...hierarchy,
levels: this.evaluateReferences(
cube.name, hierarchy.levels, { originalSorting: true }
)
levels: hierarchy.levels.map((level) => {
const member = cube.includedMembers.find(m => m.memberPath === level);

if (!member) {
return null;
}

return [cube.name, member.name].join('.');
}).filter(Boolean)
}));
}

Expand Down
6 changes: 5 additions & 1 deletion packages/cubejs-schema-compiler/src/compiler/CubeSymbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,11 @@ export class CubeSymbols {

cube.includedMembers = [...(cube.includedMembers || []), ...Array.from(new Set(finalIncludes.map((it) => {
const split = it.member.split('.');
return [split[split.length - 2], split[split.length - 1]].join('.');
const memberPath = this.pathFromArray([split[split.length - 2], split[split.length - 1]]);
return {
memberPath,
name: it.name
};
})))];
}
}
Expand Down
109 changes: 103 additions & 6 deletions packages/cubejs-schema-compiler/test/unit/hierarchies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,26 +87,45 @@ views:

await compiler.compile();

const ordersView = metaTransformer.cubes.find(it => it.config.name === 'orders_view');
expect(ordersView.config.hierarchies).toEqual([
const orders = metaTransformer.cubes.find(it => it.config.name === 'orders');
expect(orders.config.hierarchies).toEqual([
{
name: 'orders_hierarchy',
levels: [
'orders.status',
'users.state',
'orders.city',
'orders.city'
]
},
{
name: 'Some other hierarchy',
levels: [
'users.state'
'users.state',
'users.city'
]
}
]);

const ordersView = metaTransformer.cubes.find(it => it.config.name === 'orders_view');
expect(ordersView.config.hierarchies).toEqual([
{
name: 'orders_hierarchy',
levels: [
'orders_view.status',
'orders_view.state',
'orders_view.city',
]
},
{
name: 'Some other hierarchy',
levels: [
'orders_view.state'
]
},
{
name: 'Users hierarchy',
levels: [
'users.age'
'orders_view.age'
]
}
]);
Expand Down Expand Up @@ -158,7 +177,85 @@ cubes:
{
name: 'hello',
levels: [
'orders.status',
'orders_view.status',
]
},
]);
});

it('views with prefix and aliased members', async () => {
const { compiler, metaTransformer } = prepareYamlCompiler(`
views:
- name: orders_view
cubes:
- join_path: orders
prefix: true
includes: "*"
- join_path: users
prefix: false
includes:
- count
- name: gender
alias: hello_world
hierarchies:
- name: hello
levels:
- users.count
- users.gender
- orders.count
- orders.status
cubes:
- name: orders
sql: SELECT * FROM orders
measures:
- name: count
type: count
dimensions:
- name: id
sql: id
type: number
primary_key: true
- name: status
sql: status
type: string
- name: users
sql: SELECT * FROM users
measures:
- name: count
type: count
dimensions:
- name: id
sql: id
type: number
primary_key: true
- name: gender
sql: gender
type: string
- name: city
sql: city
type: string
- name: status
sql: status
type: string
`);

await compiler.compile();

const ordersView = metaTransformer.cubes.find(it => it.config.name === 'orders_view');

expect(ordersView.config.hierarchies).toEqual([
{
name: 'hello',
levels: [
'orders_view.count',
'orders_view.hello_world',
'orders_view.orders_count',
'orders_view.orders_status'
]
},
]);
Expand Down

0 comments on commit 59fddea

Please sign in to comment.