Skip to content

Commit 76dde37

Browse files
committed
dev
1 parent fc56129 commit 76dde37

File tree

1 file changed

+53
-32
lines changed

1 file changed

+53
-32
lines changed

packages/cubejs-query-orchestrator/src/orchestrator/QueryCache.ts

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ import { LoadPreAggregationResult, PreAggregationDescription } from './PreAggreg
2323
import { getCacheHash } from './utils';
2424
import { CacheAndQueryDriverType } from './QueryOrchestrator';
2525

26+
enum MetadataOperation {
27+
GET_SCHEMAS = 'GET_SCHEMAS',
28+
GET_TABLES_FOR_SCHEMAS = 'GET_TABLES_FOR_SCHEMAS',
29+
GET_COLUMNS_FOR_TABLES = 'GET_COLUMNS_FOR_TABLES'
30+
}
31+
2632
type QueryOptions = {
2733
external?: boolean;
2834
renewalThreshold?: number;
@@ -579,17 +585,17 @@ export class QueryCache {
579585
const params = req.values && req.values[0] ? JSON.parse(req.values[0]) : {};
580586

581587
switch (operation) {
582-
case 'GET_SCHEMAS':
588+
case MetadataOperation.GET_SCHEMAS:
583589
queue.logger('Getting datasource schemas', { dataSource: req.dataSource, requestId: req.requestId });
584590
return client.getSchemas();
585-
case 'GET_TABLES_FOR_SCHEMAS':
591+
case MetadataOperation.GET_TABLES_FOR_SCHEMAS:
586592
queue.logger('Getting tables for schemas', {
587593
dataSource: req.dataSource,
588594
schemaCount: params.schemas?.length || 0,
589595
requestId: req.requestId
590596
});
591597
return client.getTablesForSpecificSchemas(params.schemas);
592-
case 'GET_COLUMNS_FOR_TABLES':
598+
case MetadataOperation.GET_COLUMNS_FOR_TABLES:
593599
queue.logger('Getting columns for tables', {
594600
dataSource: req.dataSource,
595601
tableCount: params.tables?.length || 0,
@@ -1042,27 +1048,47 @@ export class QueryCache {
10421048
return this.cacheDriver.testConnection();
10431049
}
10441050

1045-
private createMetadataHash(items: any[]): string {
1046-
if (!items || items.length === 0) {
1051+
private createMetadataHash(operation: MetadataOperation, params: Record<string, any>): string {
1052+
if (!params || Object.keys(params).length === 0) {
10471053
return 'empty';
10481054
}
10491055

1050-
const sortedKeys = items
1051-
.map(item => {
1052-
if (item.schema_name && item.table_name) {
1053-
return `${item.schema_name}.${item.table_name}`;
1054-
} else if (item.schema_name && item.column_name) {
1055-
return `${item.schema_name}.${item.table_name}.${item.column_name}`;
1056-
} else if (item.schema_name) {
1057-
return item.schema_name;
1056+
// Create deterministic hash based on operation type and params
1057+
const hashData: string[] = [];
1058+
1059+
switch (operation) {
1060+
case MetadataOperation.GET_SCHEMAS:
1061+
// For schemas, we don't have any params to hash
1062+
return 'all_schemas';
1063+
1064+
case MetadataOperation.GET_TABLES_FOR_SCHEMAS:
1065+
if (params.schemas && Array.isArray(params.schemas)) {
1066+
hashData.push(...params.schemas.map(schema => schema.schema_name).sort());
10581067
}
1059-
return JSON.stringify(item);
1060-
})
1061-
.sort();
1068+
break;
1069+
1070+
case MetadataOperation.GET_COLUMNS_FOR_TABLES:
1071+
if (params.tables && Array.isArray(params.tables)) {
1072+
hashData.push(...params.tables.map(table => `${table.schema_name}.${table.table_name}`).sort());
1073+
}
1074+
break;
1075+
1076+
default:
1077+
// Fallback to JSON serialization for unknown operations
1078+
return crypto
1079+
.createHash('sha256')
1080+
.update(JSON.stringify(params))
1081+
.digest('hex')
1082+
.substring(0, 16);
1083+
}
1084+
1085+
if (hashData.length === 0) {
1086+
return 'empty';
1087+
}
10621088

10631089
return crypto
10641090
.createHash('sha256')
1065-
.update(sortedKeys.join('|'))
1091+
.update(hashData.join('|'))
10661092
.digest('hex')
10671093
.substring(0, 16);
10681094
}
@@ -1076,7 +1102,7 @@ export class QueryCache {
10761102
}
10771103

10781104
private async queryDataSourceMetadata<T>(
1079-
operation: string,
1105+
operation: MetadataOperation,
10801106
params: Record<string, any>,
10811107
dataSource: string = 'default',
10821108
options: {
@@ -1093,12 +1119,7 @@ export class QueryCache {
10931119
expiration = 7 * 24 * 60 * 60,
10941120
} = options;
10951121

1096-
let paramsHash = 'empty';
1097-
if (params.schemas) {
1098-
paramsHash = this.createMetadataHash(params.schemas);
1099-
} else if (params.tables) {
1100-
paramsHash = this.createMetadataHash(params.tables);
1101-
}
1122+
const paramsHash = this.createMetadataHash(operation, params);
11021123

11031124
const metadataQuery = this.createMetadataQuery(operation, params);
11041125
const cacheKey: CacheKey = [`METADATA:${operation}`, paramsHash, dataSource];
@@ -1137,7 +1158,7 @@ export class QueryCache {
11371158
} = {}
11381159
): Promise<QuerySchemasResult[]> {
11391160
return this.queryDataSourceMetadata<QuerySchemasResult[]>(
1140-
'GET_SCHEMAS',
1161+
MetadataOperation.GET_SCHEMAS,
11411162
{},
11421163
dataSource,
11431164
options
@@ -1155,7 +1176,7 @@ export class QueryCache {
11551176
} = {}
11561177
): Promise<QueryTablesResult[]> {
11571178
return this.queryDataSourceMetadata<QueryTablesResult[]>(
1158-
'GET_TABLES_FOR_SCHEMAS',
1179+
MetadataOperation.GET_TABLES_FOR_SCHEMAS,
11591180
{ schemas },
11601181
dataSource,
11611182
options
@@ -1173,15 +1194,15 @@ export class QueryCache {
11731194
} = {}
11741195
): Promise<QueryColumnsResult[]> {
11751196
return this.queryDataSourceMetadata<QueryColumnsResult[]>(
1176-
'GET_COLUMNS_FOR_TABLES',
1197+
MetadataOperation.GET_COLUMNS_FOR_TABLES,
11771198
{ tables },
11781199
dataSource,
11791200
options
11801201
);
11811202
}
11821203

11831204
public async clearDataSourceSchemaCache(dataSource: string = 'default') {
1184-
const cacheKey: CacheKey = ['METADATA:GET_SCHEMAS', 'empty', dataSource];
1205+
const cacheKey: CacheKey = [`METADATA:${MetadataOperation.GET_SCHEMAS}`, 'empty', dataSource];
11851206
const redisKey = this.queryRedisKey(cacheKey);
11861207
await this.cacheDriver.remove(redisKey);
11871208
this.logger('Cleared datasource schema cache', { dataSource });
@@ -1191,8 +1212,8 @@ export class QueryCache {
11911212
schemas: QuerySchemasResult[],
11921213
dataSource: string = 'default'
11931214
) {
1194-
const paramsHash = this.createMetadataHash(schemas);
1195-
const cacheKey: CacheKey = ['METADATA:GET_TABLES_FOR_SCHEMAS', paramsHash, dataSource];
1215+
const paramsHash = this.createMetadataHash(MetadataOperation.GET_TABLES_FOR_SCHEMAS, { schemas });
1216+
const cacheKey: CacheKey = [`METADATA:${MetadataOperation.GET_TABLES_FOR_SCHEMAS}`, paramsHash, dataSource];
11961217
const redisKey = this.queryRedisKey(cacheKey);
11971218
await this.cacheDriver.remove(redisKey);
11981219
this.logger('Cleared tables for schemas cache', {
@@ -1206,8 +1227,8 @@ export class QueryCache {
12061227
tables: QueryTablesResult[],
12071228
dataSource: string = 'default'
12081229
) {
1209-
const paramsHash = this.createMetadataHash(tables);
1210-
const cacheKey: CacheKey = ['METADATA:GET_COLUMNS_FOR_TABLES', paramsHash, dataSource];
1230+
const paramsHash = this.createMetadataHash(MetadataOperation.GET_COLUMNS_FOR_TABLES, { tables });
1231+
const cacheKey: CacheKey = [`METADATA:${MetadataOperation.GET_COLUMNS_FOR_TABLES}`, paramsHash, dataSource];
12111232
const redisKey = this.queryRedisKey(cacheKey);
12121233
await this.cacheDriver.remove(redisKey);
12131234
this.logger('Cleared columns for tables cache', {

0 commit comments

Comments
 (0)