diff --git a/meerkat-browser/package.json b/meerkat-browser/package.json index e230b0b2..2b817f4b 100644 --- a/meerkat-browser/package.json +++ b/meerkat-browser/package.json @@ -1,6 +1,6 @@ { "name": "@devrev/meerkat-browser", - "version": "0.0.102", + "version": "0.0.103", "dependencies": { "tslib": "^2.3.0", "@devrev/meerkat-core": "*", diff --git a/meerkat-browser/src/browser-cube-to-sql-with-resolution/browser-cube-to-sql-with-resolution.ts b/meerkat-browser/src/browser-cube-to-sql-with-resolution/browser-cube-to-sql-with-resolution.ts index 2b9bb6c4..c06d8a75 100644 --- a/meerkat-browser/src/browser-cube-to-sql-with-resolution/browser-cube-to-sql-with-resolution.ts +++ b/meerkat-browser/src/browser-cube-to-sql-with-resolution/browser-cube-to-sql-with-resolution.ts @@ -19,6 +19,7 @@ export interface CubeQueryToSQLWithResolutionParams { query: Query; tableSchemas: TableSchema[]; resolutionConfig: ResolutionConfig; + columnProjections?: string[]; contextParams?: ContextParams; } @@ -27,6 +28,7 @@ export const cubeQueryToSQLWithResolution = async ({ query, tableSchemas, resolutionConfig, + columnProjections, contextParams, }: CubeQueryToSQLWithResolutionParams) => { const baseSql = await cubeQueryToSQL({ @@ -59,7 +61,11 @@ export const cubeQueryToSQLWithResolution = async ({ connection: connection, query: { measures: [], - dimensions: generateResolvedDimensions(query, resolutionConfig), + dimensions: generateResolvedDimensions( + query, + resolutionConfig, + columnProjections + ), joinPaths: generateResolutionJoinPaths(resolutionConfig, tableSchemas), }, tableSchemas: [baseTable, ...resolutionSchemas], diff --git a/meerkat-core/package.json b/meerkat-core/package.json index 0bd4e49b..238cf2d7 100644 --- a/meerkat-core/package.json +++ b/meerkat-core/package.json @@ -1,6 +1,6 @@ { "name": "@devrev/meerkat-core", - "version": "0.0.102", + "version": "0.0.103", "dependencies": { "tslib": "^2.3.0" }, diff --git a/meerkat-core/src/resolution/resolution.spec.ts b/meerkat-core/src/resolution/resolution.spec.ts index 83e06b9a..45170199 100644 --- a/meerkat-core/src/resolution/resolution.spec.ts +++ b/meerkat-core/src/resolution/resolution.spec.ts @@ -638,6 +638,48 @@ describe('Generate resolved dimensions', () => { '__base_query.base_table__column1', ]); }); + + it('only include projected columns', () => { + const query = { + measures: ['base_table.count', 'base_table.total'], + dimensions: ['base_table.column1', 'base_table.column2'], + }; + const resolutionConfig = { + columnConfigs: [ + { + name: 'base_table.column1', + source: 'resolution_table', + joinColumn: 'id', + resolutionColumns: ['display_id'], + }, + { + name: 'base_table.column2', + source: 'resolution_table', + joinColumn: 'id', + resolutionColumns: ['id', 'display_name'], + }, + ], + tableSchemas: [], + }; + const projections = [ + 'base_table.count', + 'base_table.column2', + 'base_table.total', + ]; + + const resolvedDimensions = generateResolvedDimensions( + query, + resolutionConfig, + projections + ); + + expect(resolvedDimensions).toEqual([ + '__base_query.base_table__count', + 'base_table__column2.base_table__column2__id', + 'base_table__column2.base_table__column2__display_name', + '__base_query.base_table__total', + ]); + }); }); describe('Generate resolution join paths', () => { diff --git a/meerkat-core/src/resolution/resolution.ts b/meerkat-core/src/resolution/resolution.ts index f24b2b1e..3afe29ce 100644 --- a/meerkat-core/src/resolution/resolution.ts +++ b/meerkat-core/src/resolution/resolution.ts @@ -127,27 +127,38 @@ export const generateResolutionSchemas = ( export const generateResolvedDimensions = ( query: Query, - config: ResolutionConfig + config: ResolutionConfig, + columnProjections?: string[] ): Member[] => { - const resolvedDimensions: Member[] = [ - ...query.measures, - ...(query.dimensions || []), - ].flatMap((dimension) => { - const columnConfig = config.columnConfigs.find((c) => c.name === dimension); + // If column projections are provided, use those. + // Otherwise, use all measures and dimensions from the original query. + const aggregatedDimensions = columnProjections + ? columnProjections + : [...query.measures, ...(query.dimensions || [])]; - if (!columnConfig) { - return [ - getNamespacedKey(BASE_DATA_SOURCE_NAME, memberKeyToSafeKey(dimension)), - ]; - } else { - return columnConfig.resolutionColumns.map((col) => - getNamespacedKey( - memberKeyToSafeKey(dimension), - memberKeyToSafeKey(getNamespacedKey(columnConfig.name, col)) - ) + const resolvedDimensions: Member[] = aggregatedDimensions.flatMap( + (dimension) => { + const columnConfig = config.columnConfigs.find( + (c) => c.name === dimension ); + + if (!columnConfig) { + return [ + getNamespacedKey( + BASE_DATA_SOURCE_NAME, + memberKeyToSafeKey(dimension) + ), + ]; + } else { + return columnConfig.resolutionColumns.map((col) => + getNamespacedKey( + memberKeyToSafeKey(dimension), + memberKeyToSafeKey(getNamespacedKey(columnConfig.name, col)) + ) + ); + } } - }); + ); return resolvedDimensions; }; diff --git a/meerkat-node/package.json b/meerkat-node/package.json index eabbee17..dc2a8961 100644 --- a/meerkat-node/package.json +++ b/meerkat-node/package.json @@ -1,6 +1,6 @@ { "name": "@devrev/meerkat-node", - "version": "0.0.102", + "version": "0.0.103", "dependencies": { "@swc/helpers": "~0.5.0", "@devrev/meerkat-core": "*", diff --git a/meerkat-node/src/__tests__/resolution.spec.ts b/meerkat-node/src/__tests__/resolution.spec.ts index da65aa73..90bde754 100644 --- a/meerkat-node/src/__tests__/resolution.spec.ts +++ b/meerkat-node/src/__tests__/resolution.spec.ts @@ -348,4 +348,47 @@ describe('Resolution Tests', () => { expectedSQL.replace(/\s+/g, ' ').trim() ); }); + + it('Resolution With Column Projections', async () => { + const query = { + measures: [], + dimensions: [ + 'base_table.part_id_1', + 'base_table.random_column', + 'base_table.work_id', + 'base_table.part_id_2', + ], + }; + + const sql = await cubeQueryToSQLWithResolution({ + query, + tableSchemas: [BASE_TABLE_SCHEMA], + resolutionConfig: { + columnConfigs: [ + { + name: 'base_table.part_id_1', + source: 'dim_part', + joinColumn: 'id', + resolutionColumns: ['display_id'], + }, + ], + tableSchemas: [DIM_PART_SCHEMA, DIM_WORK_SCHEMA], + }, + columnProjections: ['base_table.random_column', 'base_table.part_id_1'], + }); + console.info(`SQL: `, sql); + const expectedSQL = ` + SELECT + "base_table__random_column", + "base_table__part_id_1 - display_id" + FROM + (SELECT __base_query.base_table__random_column AS "base_table__random_column", * FROM (SELECT base_table__part_id_1, base_table__random_column, base_table__work_id, base_table__part_id_2 FROM (SELECT base_table.part_id_1 AS base_table__part_id_1, base_table.random_column AS base_table__random_column, base_table.work_id AS base_table__work_id, base_table.part_id_2 AS base_table__part_id_2, * FROM (select * from base_table) AS base_table) AS base_table) AS __base_query + LEFT JOIN (SELECT base_table__part_id_1.display_id AS "base_table__part_id_1 - display_id", * FROM (select id, display_id from system.dim_feature UNION ALL select id, display_id from system.dim_product) AS base_table__part_id_1) AS base_table__part_id_1 + ON __base_query.base_table__part_id_1 = base_table__part_id_1.id) + AS MEERKAT_GENERATED_TABLE + `; + expect(sql.replace(/\s+/g, ' ').trim()).toBe( + expectedSQL.replace(/\s+/g, ' ').trim() + ); + }); }); diff --git a/meerkat-node/src/cube-to-sql-with-resolution/cube-to-sql-with-resolution.ts b/meerkat-node/src/cube-to-sql-with-resolution/cube-to-sql-with-resolution.ts index b7f75f4f..8ef3de8e 100644 --- a/meerkat-node/src/cube-to-sql-with-resolution/cube-to-sql-with-resolution.ts +++ b/meerkat-node/src/cube-to-sql-with-resolution/cube-to-sql-with-resolution.ts @@ -17,6 +17,7 @@ export interface CubeQueryToSQLWithResolutionParams { query: Query; tableSchemas: TableSchema[]; resolutionConfig: ResolutionConfig; + columnProjections?: string[]; contextParams?: ContextParams; } @@ -24,6 +25,7 @@ export const cubeQueryToSQLWithResolution = async ({ query, tableSchemas, resolutionConfig, + columnProjections, contextParams, }: CubeQueryToSQLWithResolutionParams) => { const baseSql = await cubeQueryToSQL({ @@ -54,7 +56,11 @@ export const cubeQueryToSQLWithResolution = async ({ const resolveParams: CubeQueryToSQLParams = { query: { measures: [], - dimensions: generateResolvedDimensions(query, resolutionConfig), + dimensions: generateResolvedDimensions( + query, + resolutionConfig, + columnProjections + ), joinPaths: generateResolutionJoinPaths(resolutionConfig, tableSchemas), }, tableSchemas: [baseTable, ...resolutionSchemas],