Skip to content

Commit fc7f779

Browse files
committed
add LightweightJoinResolver for thread-based js transpilation + pass JoinResolver to DataSchemaCompiler
1 parent 424c6c8 commit fc7f779

File tree

5 files changed

+60
-8
lines changed

5 files changed

+60
-8
lines changed

packages/cubejs-schema-compiler/src/compiler/CubeJoinsResolver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export class CubeJoinsResolver extends CubeSymbols implements CompilerInterface
99
// key: cubeName with joins defined
1010
// 1st level value: join alias
1111
// 2nd level value: join definition
12-
private cubeJoinAliases: Record<string, Record<string, JoinDefinition>>;
12+
public cubeJoinAliases: Record<string, Record<string, JoinDefinition>>;
1313

1414
// key: cubeName with joins defined
1515
// 1st level value: target cube name
@@ -27,7 +27,7 @@ export class CubeJoinsResolver extends CubeSymbols implements CompilerInterface
2727
super.compile(cubes, errorReporter);
2828

2929
this.cubeList.forEach(cube => {
30-
if (!cube.joins) {
30+
if (!cube.joins?.length) {
3131
return;
3232
}
3333

packages/cubejs-schema-compiler/src/compiler/DataSchemaCompiler.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { CompilerInterface } from './PrepareCompiler';
2222
import { YamlCompiler } from './YamlCompiler';
2323
import { CubeDictionary } from './CubeDictionary';
2424
import { CompilerCache } from './CompilerCache';
25+
import { CubeJoinsResolver } from './CubeJoinsResolver';
2526

2627
const NATIVE_IS_SUPPORTED = isNativeSupported();
2728

@@ -53,6 +54,7 @@ export type DataSchemaCompilerOptions = {
5354
cubeFactory: Function;
5455
cubeDictionary: CubeDictionary;
5556
cubeSymbols: CubeSymbols;
57+
cubeJoinsResolver: CubeJoinsResolver;
5658
cubeCompilers?: CompilerInterface[];
5759
contextCompilers?: CompilerInterface[];
5860
transpilers?: TranspilerInterface[];
@@ -72,6 +74,7 @@ export type DataSchemaCompilerOptions = {
7274
export type TranspileOptions = {
7375
cubeNames?: string[];
7476
cubeSymbols?: Record<string, Record<string, boolean>>;
77+
cubeJoins?: Record<string, Record<string, boolean>>;
7578
contextSymbols?: Record<string, string>;
7679
transpilerNames?: string[];
7780
compilerId?: string;
@@ -108,6 +111,8 @@ export class DataSchemaCompiler {
108111

109112
private readonly cubeSymbols: CubeSymbols;
110113

114+
private readonly cubeJoinsResolver: CubeJoinsResolver;
115+
111116
// Actually should be something like
112117
// createCube(cubeDefinition: CubeDefinition): CubeDefinitionExtended
113118
private readonly cubeFactory: CallableFunction;
@@ -157,6 +162,7 @@ export class DataSchemaCompiler {
157162
this.extensions = options.extensions || {};
158163
this.cubeDictionary = options.cubeDictionary;
159164
this.cubeSymbols = options.cubeSymbols;
165+
this.cubeJoinsResolver = options.cubeJoinsResolver;
160166
this.cubeFactory = options.cubeFactory;
161167
this.filesToCompile = options.filesToCompile || [];
162168
this.omitErrors = options.omitErrors || false;
@@ -232,6 +238,7 @@ export class DataSchemaCompiler {
232238
const transpile = async (stage: CompileStage) => {
233239
let cubeNames: string[] = [];
234240
let cubeSymbols: Record<string, Record<string, boolean>> = {};
241+
let cubeJoins: Record<string, Record<string, boolean>> = {};
235242
let transpilerNames: string[] = [];
236243
let results;
237244

@@ -252,6 +259,14 @@ export class DataSchemaCompiler {
252259
)],
253260
),
254261
);
262+
cubeJoins = Object.fromEntries(
263+
Object.entries(this.cubeJoinsResolver.cubeJoinAliases as Record<string, Record<string, any>>)
264+
.map(
265+
([key, value]: [string, Record<string, any>]) => [key, Object.fromEntries(
266+
Object.keys(value).map((k) => [k, true]),
267+
)],
268+
),
269+
);
255270

256271
// Transpilers are the same for all files within phase.
257272
transpilerNames = this.transpilers.map(t => t.constructor.name);
@@ -264,7 +279,7 @@ export class DataSchemaCompiler {
264279
content: ';',
265280
};
266281

267-
await this.transpileJsFile(dummyFile, errorsReport, { cubeNames, cubeSymbols, transpilerNames, contextSymbols: CONTEXT_SYMBOLS, compilerId, stage });
282+
await this.transpileJsFile(dummyFile, errorsReport, { cubeNames, cubeSymbols, cubeJoins, transpilerNames, contextSymbols: CONTEXT_SYMBOLS, compilerId, stage });
268283

269284
const nonJsFilesTasks = toCompile.filter(file => !file.fileName.endsWith('.js'))
270285
.map(f => this.transpileFile(f, errorsReport, { transpilerNames, compilerId }));
@@ -291,7 +306,7 @@ export class DataSchemaCompiler {
291306

292307
results = (await Promise.all([...nonJsFilesTasks, ...JsFilesTasks])).flat();
293308
} else if (transpilationWorkerThreads) {
294-
results = await Promise.all(toCompile.map(f => this.transpileFile(f, errorsReport, { cubeNames, cubeSymbols, transpilerNames })));
309+
results = await Promise.all(toCompile.map(f => this.transpileFile(f, errorsReport, { cubeNames, cubeSymbols, cubeJoins, transpilerNames })));
295310
} else {
296311
results = await Promise.all(toCompile.map(f => this.transpileFile(f, errorsReport, {})));
297312
}
@@ -405,7 +420,7 @@ export class DataSchemaCompiler {
405420
});
406421
}
407422

408-
private async transpileJsFile(file: FileContent, errorsReport: ErrorReporter, { cubeNames, cubeSymbols, contextSymbols, transpilerNames, compilerId, stage }: TranspileOptions) {
423+
private async transpileJsFile(file: FileContent, errorsReport: ErrorReporter, { cubeNames, cubeSymbols, cubeJoins, contextSymbols, transpilerNames, compilerId, stage }: TranspileOptions) {
409424
try {
410425
if (getEnv('transpilationNative')) {
411426
const reqData = {
@@ -417,6 +432,7 @@ export class DataSchemaCompiler {
417432
metaData: {
418433
cubeNames,
419434
cubeSymbols: cubeSymbols || {},
435+
cubeJoins: cubeJoins || {},
420436
contextSymbols: contextSymbols || {},
421437
stage: stage || 0 as CompileStage,
422438
},
@@ -437,6 +453,7 @@ export class DataSchemaCompiler {
437453
transpilers: transpilerNames,
438454
cubeNames,
439455
cubeSymbols,
456+
cubeJoins,
440457
};
441458

442459
const res = await this.workerPool!.exec('transpile', [data]);

packages/cubejs-schema-compiler/src/compiler/PrepareCompiler.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { CompilerCache } from './CompilerCache';
2424
import { YamlCompiler } from './YamlCompiler';
2525
import { ViewCompilationGate } from './ViewCompilationGate';
2626
import type { ErrorReporter } from './ErrorReporter';
27+
import { CubeJoinsResolver } from './CubeJoinsResolver';
2728

2829
export type PrepareCompilerOptions = {
2930
nativeInstance?: NativeInstance,
@@ -46,6 +47,7 @@ export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareComp
4647
const nativeInstance = options.nativeInstance || new NativeInstance();
4748
const cubeDictionary = new CubeDictionary();
4849
const cubeSymbols = new CubeSymbols();
50+
const cubeJoinsResolver = new CubeJoinsResolver();
4951
const viewCompiler = new CubeSymbols(true);
5052
const viewCompilationGate = new ViewCompilationGate();
5153
const cubeValidator = new CubeValidator(cubeSymbols);
@@ -62,7 +64,7 @@ export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareComp
6264
const transpilers: TranspilerInterface[] = [
6365
new ValidationTranspiler(),
6466
new ImportExportTranspiler(),
65-
new CubePropContextTranspiler(cubeSymbols, cubeDictionary, viewCompiler),
67+
new CubePropContextTranspiler(cubeSymbols, cubeDictionary, viewCompiler, cubeJoinsResolver),
6668
];
6769

6870
if (!options.allowJsDuplicatePropsInSchema) {
@@ -73,7 +75,7 @@ export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareComp
7375

7476
const compiler = new DataSchemaCompiler(repo, Object.assign({}, {
7577
cubeNameCompilers: [cubeDictionary],
76-
preTranspileCubeCompilers: [cubeSymbols, cubeValidator],
78+
preTranspileCubeCompilers: [cubeSymbols, cubeValidator, cubeJoinsResolver],
7779
transpilers,
7880
viewCompilationGate,
7981
compiledScriptCache,
@@ -84,6 +86,7 @@ export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareComp
8486
compilerCache,
8587
cubeDictionary,
8688
cubeSymbols,
89+
cubeJoinsResolver,
8790
extensions: {
8891
Funnels,
8992
RefreshKeys,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { TranspilerSymbolResolver } from './transpiler.interface';
2+
import { CONTEXT_SYMBOLS, CURRENT_CUBE_CONSTANTS } from '../CubeSymbols';
3+
4+
export class LightweightJoinResolver implements TranspilerSymbolResolver {
5+
public constructor(private cubeJoinAliases: Record<string, Record<string, boolean>> = {}) {
6+
}
7+
8+
public setJoinAliases(cubeJoinAliases: Record<string, Record<string, boolean>>) {
9+
this.cubeJoinAliases = cubeJoinAliases;
10+
}
11+
12+
public isCurrentCube(name: string): boolean {
13+
return CURRENT_CUBE_CONSTANTS.indexOf(name) >= 0;
14+
}
15+
16+
public resolveSymbol(cubeName: string, name: string): any {
17+
if (name === 'USER_CONTEXT') {
18+
throw new Error('Support for USER_CONTEXT was removed, please migrate to SECURITY_CONTEXT.');
19+
}
20+
21+
if (CONTEXT_SYMBOLS[name]) {
22+
return true;
23+
}
24+
25+
const cube = this.cubeJoinAliases[this.isCurrentCube(name) ? cubeName : name];
26+
return !!(cube || this.cubeJoinAliases[cubeName]?.[name]);
27+
}
28+
}

packages/cubejs-schema-compiler/src/compiler/transpilers/transpiler_worker.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,33 @@ import { CubePropContextTranspiler } from './CubePropContextTranspiler';
1010
import { ErrorReporter } from '../ErrorReporter';
1111
import { LightweightSymbolResolver } from './LightweightSymbolResolver';
1212
import { LightweightNodeCubeDictionary } from './LightweightNodeCubeDictionary';
13+
import { LightweightJoinResolver } from './LightweightJoinResolver';
1314

1415
type TransferContent = {
1516
fileName: string;
1617
content: string;
1718
transpilers: string[];
1819
cubeNames: string[];
1920
cubeSymbols: Record<string, Record<string, boolean>>;
21+
cubeJoins: Record<string, Record<string, boolean>>;
2022
};
2123

2224
const cubeDictionary = new LightweightNodeCubeDictionary();
2325
const cubeSymbols = new LightweightSymbolResolver();
26+
const cubeJoinsResolver = new LightweightJoinResolver();
2427
const errorsReport = new ErrorReporter(null, []);
2528

2629
const transpilers = {
2730
ValidationTranspiler: new ValidationTranspiler(),
2831
ImportExportTranspiler: new ImportExportTranspiler(),
2932
CubeCheckDuplicatePropTranspiler: new CubeCheckDuplicatePropTranspiler(),
30-
CubePropContextTranspiler: new CubePropContextTranspiler(cubeSymbols, cubeDictionary, cubeSymbols),
33+
CubePropContextTranspiler: new CubePropContextTranspiler(cubeSymbols, cubeDictionary, cubeSymbols, cubeJoinsResolver),
3134
};
3235

3336
const transpile = (data: TransferContent) => {
3437
cubeDictionary.setCubeNames(data.cubeNames);
3538
cubeSymbols.setSymbols(data.cubeSymbols);
39+
cubeJoinsResolver.setJoinAliases(data.cubeJoins);
3640

3741
const ast = parse(
3842
data.content,

0 commit comments

Comments
 (0)